我有一个数组,用于定义另一个数组的排序顺序。例如,要对包含char * data[] = {"c", "b", "a"};
的数组进行排序,sort_order
数组将为{2, 1, 0}
- 当数组排序时,第一个元素应为"c"
(即{ {1}})。
(背景是我有两个我要排序的数组,但第二个数组应该使用与第一个相同的排序顺序。所以基本上我使用第一个的值排序data[sort_order[0]]
数组,然后我使用此排序顺序对两个数组的实际值进行排序。)
显而易见的解决方案是创建数组的副本({0, 1, 2}
),然后为每个元素分配排序顺序定义的正确值:
new_data
但是,这需要制作数组的副本。有没有办法可以交换原始数组的元素来对它们进行排序,而不必复制数组?
编辑:"possible duplicate"确实使用了另一个数组,这正是我想要避免的。
答案 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) );
}