在C中排序后跟踪数组的原始索引
Posted
技术标签:
【中文标题】在C中排序后跟踪数组的原始索引【英文标题】:keeping track of the original indices of an array after sorting in C 【发布时间】:2014-08-26 12:19:13 【问题描述】:我有一个数组,比如说A[5]
,5 个元素是5,4,1,2,3
。现在我按升序对这些数组进行排序。所以结果数组现在将是1,2,3,4,5
。我使用stdlib.h
的qsort()
函数对其进行排序。问题是如何获得原始数组相对于我的新数组的索引。最初我的索引是0,1,2,3,4
对应的5,4,1,2,3
值,现在索引已更改为2、3、4、1、0。如何在 C 中有效地获取这些索引?提前谢谢(如果可能请写代码)
【问题讨论】:
不是对数组本身进行排序,而是创建一个索引数组并对 that 进行排序,并使用比较器函数来比较索引值。 你能举个例子吗?这对我来说并不完全清楚 好吧,你想让comp(i, j)
返回a[i] < a[j]
(而不是i < j
)等等
你能帮我解决这个问题吗?我将用一个例子来澄清。 5,4,1,2,3 是我未排序的数组。现在我得到了一个索引。让我们取第三个索引,第三个索引的值是 2。现在我必须在数组排序后找到值 2 的索引。我该怎么做?
【参考方案1】:
在有限的条件下还有如下方法。
#include <stdio.h>
int main(void)
int data[] = 5,4,1,2,3 ; //Without duplication, The number of limited range.
int size = sizeof(data)/sizeof(*data);
int keys[size];
int i;
printf("data :\n");
for(i=0;i<size;i++)
printf("%d ",data[i]);
for(i=0;i<size;i++)
keys[data[i]-1]=i;
printf("\n\ndata\tindex\n");
for(i=0;i<size;i++)
printf("%d\t%d\n", data[keys[i]], keys[i]);
return 0;
/* result sample
data :
5 4 1 2 3
data index
1 2
2 3
3 4
4 1
5 0
*/
建议如何对索引数组@Kerrek 进行排序。
#include <stdio.h>
#include <stdlib.h>
int *array;
int cmp(const void *a, const void *b)
int ia = *(int *)a;
int ib = *(int *)b;
return array[ia] < array[ib] ? -1 : array[ia] > array[ib];
int main(void)
int data[] = 5,4,1,2,3 ;
int size = sizeof(data)/sizeof(*data);
int index[size];//use malloc to large size array
int i;
for(i=0;i<size;i++)
index[i] = i;
array = data;
qsort(index, size, sizeof(*index), cmp);
printf("\n\ndata\tindex\n");
for(i=0;i<size;i++)
printf("%d\t%d\n", data[index[i]], index[i]);
return 0;
【讨论】:
限制是多少?我可以将此方法用于数组中的 10^5 个元素吗?我的整数的最大大小是 10^9。 @user3807678 我认为这可能是Kerrek 之类的一般建议。我已经添加了示例代码。 非常感谢您的代码!我已经获得了一个值的旧索引,我必须在排序数组中找到该值的新索引。我们如何在同一个例子中做到这一点? @user3807678 我不知道你在说什么。你想要i
吗?
我会用一个例子来说明。 5,4,1,2,3 是我未排序的数组。现在我得到了一个索引。让我们取第三个索引,第三个索引的值是 2。现在我必须在数组排序后找到值 2 的索引。我该怎么做?【参考方案2】:
获取一个二维数组。将数字存储在第一列,然后将相应的索引存储在第二列。您可以将比较器函数编写为:
int compare ( const void *pa, const void *pb )
const int *a = pa;
const int *b = pb;
if(a[0] == b[0])
return a[1] - b[1];
else
return a[0] - b[0];
致电qsort
应为:
qsort(array, n, sizeof array[0], compare); // n is representing rows
见Live Demo
【讨论】:
【参考方案3】:#include <limits.h>
#include <stdio.h>
#define SIZE 5
int* sortArrayNKeepIndices(int arr[], int arrSize)
static int indexArr[SIZE];
int arr2[arrSize];
for (int i = 0; i < arrSize; i++)
indexArr[i] = 0;
arr2[i] = arr[i];
int min = 0, temp = 0;
for (int i = 0; i < arrSize ; i++)
min = i; // record the position of the smallest
for (int j = i + 1; j < arrSize; j++)
// update min when finding a smaller element
if (arr[j] < arr[min])
min = j;
// put the smallest element at position i
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
// array sorting ends here
int ctr = 0;
while ( ctr < arrSize)
min = 0; // restart from first element
for (int j = 0; j < arrSize; j++)
if (arr2[j] == INT_MAX) continue; // ignore already marked as minimum indices
// update min when finding a smaller element
if (arr2[j] < arr2[min])
min = j;
indexArr[ctr] = min; // updating indexArr with the index of the next minimum
arr2[min] = INT_MAX; // marking minimum element to be ignored next time
ctr++;
//keeping track of previous indices of the array elements ends here
return indexArr;
// function sortArrayKeepIndices ends here
int main ()
int arr[SIZE] = 16, 15, 12, 10, 13;
int* ptr = sortArrayNKeepIndices(arr, SIZE);
for (int dex = 0; dex < SIZE; dex++)
printf("%d (%d, %d)\t", arr[dex], * (ptr + dex), dex);
// 输出将是 10 (3, 0) 12 (2, 1) 13 (4, 2) 15 (1, 3) 16 (0, 4) // 元素(旧索引,新索引)
【讨论】:
以上是关于在C中排序后跟踪数组的原始索引的主要内容,如果未能解决你的问题,请参考以下文章