我有一个包含多个数组的结构。我需要能够对这些数组中的任何一个进行排序,并根据排序后的数组移动其他数组中的元素。
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
最佳答案
在必须对多个独立数据结构执行同步重排的情况下,您可以采用以下两种方法之一:
- @wallyk 提到的侵入式“内部”方法 - 即提供您自己的交换函数,同步交换所有三个数组中的元素。
- 非侵入式“外部”方法 - 将排序过程分解为两个独立的步骤:首先,从“主”数组生成排序排列,然后将该排序排列独立应用于三个数组中的每一个。
第一种方法可能更容易实现,但它有一些明显的缺点。随着数据集数量的增加和/或元素本身变得更重,交换功能也变得更重。这对于基于元素物理复制的排序算法来说不是一件好事,因为此类算法可能会多次重新定位(交换)每个元素。
第二种方法本质上是基于间接的索引排序,这意味着它对元素复制的重量不太敏感。第二种方法只复制每个实际元素一次,当它知道其最终位置时。
要生成排序排列,您需要做的就是取一个整数 index 数组 p
,用 { 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
的排序版本>,位置 i
的元素应来自 values1[p[i]]
。现在,您需要做的就是使用相同的 from-permutation p 生成
。values1
、values2
和 values3
的重新排列版本
同样,后一步很容易在异地做,而在原地做更难。在这里你可以找到一些相关的原位重排的实现:In-place array reordering?
关于c - 使用 qsort 对多个数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22077130/