使用合并排序在c中排序时保留原始索引

时间:2016-01-19 08:14:22

标签: c arrays sorting mergesort

我正在尝试使用Merge Sort algoritm对列表进行排序,同时保留其原始索引。我被告知,直接的解决方案是使用索引数组(显然它将初始化为0 1 2 3 ...),并在合并排序中更改它,因为我更改了原始中的相应值阵列。 问题是,我找不到让它工作的方法,因为merge sort不使用原始数组的索引,而是使用原始数组拆分的小数组的索引。我想我在这里遗漏了一些东西...我到目前为止所考虑的解决方案是将索引数组视为原始数组,我的意思是将其拆分为更小的数组,为新索引声明“helperIndexArray”,调用合并与那些变量等...但它似乎真的很无效。有没有更好的方法? 我很感激任何提示,谢谢!

void internalMsort(int array[], int size, int helperArray[], int index[]) {
    int left = size / 2, right = size - left;
    if (size < 2)
        return;
    internalMsort(array, left, helperArray);
    internalMsort(array + left, right, helperArray);
    merge(array, left, array + left, right, helperArray, index);
    memCpy(array, helperArray, size);
}

void merge(int a[], int na, int b[], int nb, int c[], index[]) {
int ia, ib, ic;
   for(ia = ib = ic = 0; (ia < na) && (ib < nb); ic++)
     {
       if(a[ia] < b[ib]) {
           c[ic] = a[ia];
           ia++;
           // here I was trying to swap index[ic] with index[ia] but it didn't work
       }
       else {
           c[ic] = b[ib];
           ib++;
       }
   }
   for(;ia < na; ia++, ic++){ c[ic] = a[ia]; }
   for(;ib < nb; ib++, ic++) { c[ic] = b[ib]; }
}

3 个答案:

答案 0 :(得分:3)

定义一个名为tuple的新类型:

typedef struct
{
    int value;
    size_t index;
} tuple;

创建一个元组数组,用值填充它,并按顺序设置索引,从0到size-1。

然后使用成员值对数组进行排序,并忽略成员索引。

生成的数组将被排序,其元素将包含成员索引中的原始索引。

答案 1 :(得分:0)

这很容易(并非特定于 mergesort )。只需创建一个

数组
 struct element_and_index_st  {
    int element;
    size_t original_index; // could be an `int` or an `unsigned`
 };

并对该数组进行排序,提供仅比较element字段的比较函数。

(除非你的阵列很大,你几乎可以在当前桌面或笔记本电脑上original_indexint或某些unsignedint s至少有32位)

但是你不知道为什么你需要原始索引以及如何将它们交还给你的来电者?

也许你只想要一些stable sort

答案 2 :(得分:0)

首先根据数组(比较数组[index [ia]]&lt; = array [index [ic]]对索引[]进行排序。使用辅助数组作为索引的第二个数组。数组和索引是整数,你可以使用辅助数组在索引排序后对数组进行排序:

    for(i = 0; i < size; i++)
        helperArray = array[index[i]];
    for(i = 0; i < size; i++)
        array[i] = helperArray[i];