我有一个包含多个数组的结构。我需要能够对这些数组中的任何一个进行排序,并根据排序的数组移动其他数组中的元素。
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 :(得分:4)
在必须执行多个独立数据结构的同步重新排列的情况下,您可以遵循以下两种方法之一:
第一种方法可能更容易实现,但它有一些明显的缺点。随着数据集的数量增加和/或元素本身变得更重,交换功能也变得更重。这对于基于元素的物理复制的算法排序来说不是一件好事,因为这样的算法可能会多次重新定位(交换)每个元素。
第二种方法本质上是基于间接的索引排序,这意味着它对重复元素复制的敏感程度较低。第二种方法只有在知道最终位置时才复制每个实际元素一次。
要生成排序排列,您只需要使用p
初始化的整数 index 数组{ 0, 1, 2, 3, ... }
。不是直接排序values1
,而是对此索引数组p
进行排序,以使其为values1
数组生成正确的排序。 (标准qsort
函数对于此类应用程序不能很好地工作,因为它是无上下文的。)
排序后,该索引数组将作为您的排列。您需要做的就是根据排列重新排列三个阵列中的每一个。根据您的需要,它可以就地完成,也可以更容易,不合时宜地完成。
在您的具体示例中,您将从索引数组
开始p = { 0, 1, 2, 3, 4, 5 }
排序后会变成
p = { 5, 1, 4, 0, 3, 2 }
这是values1
数组的所谓 from-permutation :它告诉您为了获得values1
的排序版本,位置{ {1}}应从 i
中获取。现在,您需要做的就是使用相同的from-permutation values1[p[i]]
生成重新排列的values1
,values2
和values3
版本。
同样,后一步很容易做到不合适,而且更难以就地完成。在这里,您可以找到针对来自排列的就地重新排列的一些相关实现:In-place array reordering?
答案 1 :(得分:1)
每当我遇到这种类型的问题时,我会抓住一个qsort实现并修改它以接受 - 除了比较函数 - 一个额外的交换函数。
通过这种方式,您可以交换所有并行数据中的项目。
答案 2 :(得分:0)
#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];
}
}