基于另一个数组的内容对C数组进行排序

时间:2011-05-20 19:27:39

标签: c arrays sorting

我正在尝试对其元素为索引的数组A进行排序。索引引用另一个数组B,其值将确定A的顺序。所以,我想对A进行排序,B[ A[i] ]正在增加。

例如:

A = [0, 1, 4, 5, 7]
B = [5, 3, 8, 2, 2, 7, 1, 6, 3, 9]

排序A将是

A' = [ 7, 4, 1, 0, 5 ]

这可能是C的内置排序,还是我必须编写自己的实现?

编辑:这些数组是局部函数变量。

5 个答案:

答案 0 :(得分:6)

如果你想使用qsort,最好的办法是将A中的索引和B中的值重新包装成一个struct,然后根据一个新的数组创建一个比较器结构。例如:

typedef struct
{
    int index_from_A;
    int value_from_B;
} index_value_wrapper;

index_value_wrapper index_wrapper_array[5];

for (int i=0; i < 5; i++)
{
    index_wrapper_array[i].index_from_A = A[i];
    index_wrapper_array[i].value_from_B = B[A[i]];
}

int comparitor (const void* lhs, const void* rhs)
{
    return (lhs.value_from_B - rhs.value_from_B);
}

现在,您可以在struct数组上运行qsort,然后您可以从中提取原始数组A所需的正确排序顺序,而无需使用自定义排序功能。

答案 1 :(得分:4)

如果您有空,qsort_r提供了一种方法。您可以在附加参数中为其提供上下文信息。该上下文传递给比较函数。您可以访问该附加信息以提取所需的排序信息。

Microsoft编译器具有类似的编译器:qsort_s

答案 2 :(得分:3)

我认为您可以使用qsort和自定义比较器

int comparator(const void *x, const void *y)
{
    return ( b[*(int*)x] - b[*(int*)y] );
}

答案 3 :(得分:1)

使用您的规则作为qsort的比较函数(只要B长于A):

#include <stdio.h>
#include <stdlib.h>

int A[] = {0, 1, 4, 5, 7};
int B[]= {5, 3, 8, 2, 2, 7, 1, 6, 3, 9};

 int my_cmp(const void *a_, const void *b_,void *arg_)
 {
   const int *a = a_, *b = b_;

   if(B[*a] == B[*b])
       return 0;
    else if (B[*a] < B[*b])
        return -1;
    else
        return 1;

}

int main(int argc,char *arga[])
{
    int i;

    qsort(A,sizeof A/sizeof A[0] ,sizeof A[0],my_cmp);

    puts("Sorted A");
    for(i = 0 ; i < sizeof A/sizeof A[0]; i++) {
        printf("A[%d] : %d B[A[%d]] : %d\n",i,A[i],i,B[A[i]]);
    }

    return 0;
}

这给出了:

$ ./a.out
Sorted A
A[0] : 4 B[A[0]] : 2
A[1] : 1 B[A[1]] : 3
A[2] : 0 B[A[2]] : 5
A[3] : 7 B[A[3]] : 6
A[4] : 5 B[A[4]] : 7

在许多平台上都可以使用qsort_r(在linux上你必须#define _GNU_SOURCE才能包含<stdlib.h>使用它。使用它,你可以将比较功能更改为例如。

int my_cmp(const void *a_, const void *b_,void *arg_)
 {
    const int *a = a_, *b = b_, *arg = arg_;

   if(arg[*a] == arg[*b])
       return 0;
    else if (arg[*a] < arg[*b])
        return -1;
    else
        return 1;

}

并调用qsort_r,如

qsort_r(A,sizeof A/sizeof A[0] ,sizeof A[0],my_cmp,B);

答案 4 :(得分:1)

创建另一个类型为struct { int a_value; int b_value}的数组C,将每个元素初始化为a的每个索引的值,并从b中查找值。对其进行排序,遍历已排序的C,将a_values复制回A。

中提琴。不,那是一把大小提琴。瞧!