根据另一个数组中定义的排序顺序对数组进行排序

时间:2016-06-11 03:01:13

标签: c arrays sorting

我有一个数组,用于定义另一个数组的排序顺序。例如,要对包含char * data[] = {"c", "b", "a"};的数组进行排序,sort_order数组将为{2, 1, 0} - 当数组排序时,第一个元素应为"c"(即{ {1}})。

(背景是我有两个我要排序的数组,但第二个数组应该使用与第一个相同的排序顺序。所以基本上我使用第一个的值排序data[sort_order[0]]数组,然后我使用此排序顺序对两个数组的实际值进行排序。)

显而易见的解决方案是创建数组的副本({0, 1, 2}),然后为每个元素分配排序顺序定义的正确值:

new_data

但是,这需要制作数组的副本。有没有办法可以交换原始数组的元素来对它们进行排序,而不必复制数组?

编辑:"possible duplicate"确实使用了另一个数组,这正是我想要避免的。

1 个答案:

答案 0 :(得分:1)

重新排序,通过旋转“循环”对A []和I []进行排序。每个商店都在其正确的位置放置一个值,因此时间复杂度为O(n)。

1,2,3,4,5,6,7,8

我刚注意到你正在使用C.在C ++中,你可以使用lambda compare函数来比较A []的成员,基于I []中的索引。对于C,您可以使用指针数组P []而不是索引数组I []。

    // reorder A in place according to sorted indices in I
    // tA is temp value for A
    for(i = 0; i < n; i++){
        if(i != I[i]){
            tA = A[i];
            k = i;
            while(i != (j = I[k])){
                A[k] = A[j];
                I[k] = k;
                k = j;
            }
            A[k] = tA;
            I[k] = k;
        }
    }

如果A []包含整数,则qsort()的自定义比较示例。由于qsort()将指针传递给P []作为compare()的参数,并且由于P []是一个指针数组,因此传递给compare()的参数是指针的指针。

    /* create array of pointers to A[] */
    for(i = 0; i < n; i++)
        P[i] = &A[i];
    /* sort array of pointers, compare is custom compare function */
    qsort(P, n, sizeof(P[0]), compare);
    /* reorder A[] according to the array of pointers */
    for(i = 0; i < n; i++){
        if(i != P[i]-a){
            tA = A[i];
            k = i;
            while(i != (j = P[k]-a)){
                A[k] = A[j];
                P[k] = &A[k];
                k = j;
            }
            A[k] = tA;
            P[k] = &A[k];
        }
    }

如果目标是根据排序A []对第二个数组B []进行排序,则添加以下行:

int compare(const void *pp0, const void *pp1)
{
    return( (**(int **)pp0) - (**(int **)pp1) );
}