数组排序同时返回元素在原数组中的位置

对数组中的元素进行排序是非常基础的问题,从现有的众多排序算法中任选一种即可实现。但是如果要求排序后同时返回新的(有序)数组中每个元素在旧的(未排序)数组中之原始位置,问题可能就变得有些棘手了。

例如假设有一个数组如下:

[2, 30, 1, 5, 12, 8, 6]

排序(从小到大)后可得新的数组如下:

[1, 2, 5, 6, 8, 12, 30]

那么对于新数组中值等于1的元素而言,其在原数组中的位置就应该是2(注意数组下标从0开始计数)。


当然,最straightforward的想法就是回到原数组中去search,从而获得元素在其中的位置。但这样做的代价显然有点高,比较对每个元素都做一次搜索还是相当浪费的。从执行时间复杂度来看,有没有更好的办法呢?所以更常被使用的方法是使用一个结构体数组,例如下面这种形式:

struct value_index_pair
{
    double value;
    int index;
};

也就是说,对于原数组中的每个元素,我们在一个结构体中既存放它的值(value),也存放它在数组中的位置(index)。接下来的问题就相对简单了。当我们执行排序算法的时候,如果需要将两个元素交换位置,那么我们不仅会交互这两个元素的value,同时也会交换它们的index。这样就方便很多了!


来看下面这段示例代码。因为排序算法本身并不是我们所关注的焦点,所以我们之间调用C语言的库函数qsort()来执行排序过程。

#include <stdio.h>
#include <stdlib.h>

#define SIZE 7

int comp(const void *a, const void *b)
{
    return (*(struct value_index_pair *)a).value - (*(struct value_index_pair *)b).value;
}

int main(int argc, const char * argv[]) {
    
    struct value_index_pair * sequence = malloc(SIZE * sizeof(struct value_index_pair));
    
    struct value_index_pair * ps;
    ps = &sequence[0];
    
    double array[7] = {2.0, 30.0, 1.0, 5.0, 12.0, 8.0, 6.0};
    for(int i = 0; i < SIZE; i++)
    {
        ps[i].index = i;
        ps[i].value = array[i];
    }
    
    qsort(sequence, SIZE, sizeof(struct value_index_pair), comp);
    
    //输出排序后的结果
    for(int i = 0; i < SIZE; i++)
    {
        printf("[%d] value: %.1f index: %d\n", i, ps[i].value, ps[i].index);
    }
    
    free(sequence);
    sequence = NULL;
    
    return 0;
}

执行上述程序,可得输出结果如下:

[0] value: 1.0 index: 2
[1] value: 2.0 index: 0
[2] value: 5.0 index: 3
[3] value: 6.0 index: 6
[4] value: 8.0 index: 5
[5] value: 12.0 index: 4
[6] value: 30.0 index: 1

可见我们的程序执行正确。


(本文完)

    原文作者:算法
    原文地址: https://blog.csdn.net/baimafujinji/article/details/49452613
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞