繁体   English   中英

使用qsort对多个数组进行排序

[英]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

在必须对几个独立数据结构进行同步重排的情况下,可以采用以下两种方法之一:

  1. @wallyk提到的一种侵入式“内部”方法-即提供您自己的交换函数,该函数将同步交换所有三个数组中的元素。
  2. 一种非侵入式的“外部”方法-将排序过程分解为两个独立的步骤:首先,从“主”数组生成排序排列,然后将排序排列独立地应用于三个数组中的每一个。

第一种方法可能更易于实现,但有一些明显的缺点。 随着数据集数量的增加和/或元素本身变重,交换功能也变重。 对于基于元素物理复制的排序算法而言,这不是一件好事,因为此类算法可能会多次定位(交换)每个元素。

第二种方法固有地基于间接的索引排序,这意味着它对重元素复制的敏感程度较低。 第二种方法在知道其最终位置时仅复制每个实际元素一次。

要生成排序排列,您所需要做的就是获取一个用{ 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生成values1values2values3的重新排列版本。

同样,后一步很容易在原地进行,而在原地进行则更加困难。 在这里,您可以找到针对置换的就地重排的一些相关实现: 就地数组重新排序?

每当遇到此类问题时,我都会抓住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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM