[英]using qsort to sort multiple arrays
我有一个包含几个数组的结构。 我需要能够对任何这些数组进行排序,并使其他数组中的元素根据已排序的数组进行移动。
struct arrayset
{
int values1[] = { 32, 10, 101, 72, 13, 5 };
int values2[] = { 40, 10, 100, 90, 20, 2 };
int values3[] = { 16, 14, 93, 2, 37, 39 };
};
我知道如何只用一个来做,但是我不确定改变其他两个数组中元素的优雅方法。 我不尝试对其他两个数组进行排序,但我希望元素继续匹配帖子排序,而不是混淆。 有什么建议么?
qsort(arrayset.values1,6,sizeof(int), compare);
//values2/3 elements would follow values1's elements
在必须对几个独立数据结构进行同步重排的情况下,可以采用以下两种方法之一:
第一种方法可能更易于实现,但有一些明显的缺点。 随着数据集数量的增加和/或元素本身变重,交换功能也变重。 对于基于元素物理复制的排序算法而言,这不是一件好事,因为此类算法可能会多次定位(交换)每个元素。
第二种方法固有地基于间接的索引排序,这意味着它对重元素复制的敏感程度较低。 第二种方法在知道其最终位置时仅复制每个实际元素一次。
要生成排序排列,您所需要做的就是获取一个用{ 0, 1, 2, 3, ... }
初始化的整数索引数组p
。 与其直接对values1
进行排序, values1
索引数组p
进行排序,以使其为您的values1
数组产生正确的排序。 (由于标准qsort
函数是无上下文的,因此它不适用于此类应用程序。)
排序后,该索引数组将作为您的排列。 您需要做的就是根据该排列重新排列三个数组中的每个数组。 它可以就地完成,也可以更轻松地就地完成,具体取决于您的需求。
在您的特定示例中,您将从索引数组开始
p = { 0, 1, 2, 3, 4, 5 }
排序后将变成
p = { 5, 1, 4, 0, 3, 2 }
这是values1
数组的所谓的from-permutation :它告诉您为了获得values1
的排序版本,位置i
处的元素应从 values1[p[i]]
。 现在,您需要做的就是使用相同的values3
置换p
生成values1
, values2
和values3
的重新排列版本。
同样,后一步很容易在原地进行,而在原地进行则更加困难。 在这里,您可以找到针对置换的就地重排的一些相关实现: 就地数组重新排序?
每当遇到此类问题时,我都会抓住qsort实现并将其修改为接受(除了比较功能之外)附加的交换功能。
这样,您可以交换所有并行数据中的项目。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct arrayset {
int *values1;
int *values2;
int *values3;
};
void custom_sort(struct arrayset *v, size_t size);
int main() {
struct arrayset work = {
(int []){ 32, 10, 101, 72, 13, 5 },
(int []){ 40, 10, 100, 90, 20, 2 },
(int []){ 16, 14, 93, 2, 37, 39}
};
custom_sort(&work, 6);
for(int i=0;i<6;++i){
printf("%d, %d, %d\n",
work.values1[i], work.values2[i], work.values3[i]);
}
return 0;
}
typedef struct pair {
int key, value;
} Pair;
int cmp(const void *x, const void *y){
int a = ((const Pair*)x)->key;
int b = ((const Pair*)y)->key;
return a < b ? -1 : a > b;
}
void custom_sort(struct arrayset *v, size_t size){
Pair key[size];
for(int i=0;i<size;++i){
key[i].key = v->values1[i];
key[i].value=i;
}
qsort(key, size, sizeof(Pair), cmp);
int v1[size], v2[size], v3[size];
memcpy(v1, v->values1, size*sizeof(int));
memcpy(v2, v->values2, size*sizeof(int));
memcpy(v3, v->values3, size*sizeof(int));
for(int i=0;i<size;++i){
v->values1[i] = v1[key[i].value];
v->values2[i] = v2[key[i].value];
v->values3[i] = v3[key[i].value];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.