索引排序

来源:互联网 发布:网吧网络组建方案 编辑:程序博客网 时间:2024/05/19 06:37

索引排序

在排序时,若是数据很复杂,对数据的移动显然是费时的。若把数据移动改为索引(或指针)移动,则减少了操作复杂度。索引排序,也叫地址排序,就是这种排序思想。

索引含义

根据索引的含义不同,索引排序的算法上也主要分为两种。

一、index[i]为array[i]最终在有序序列中的位置。

二、index[i]为位置i上最终应存放元素的下标。即最终元素按array[index[0]]、array[index[1]]……有序。

一个实例

原序列 array: 17  19  23  21  38  5   33  22

        下标:0   1   2   3   4   5   6   7

      index1:1   2   5   3   7   0   6   4

      index2:5   0   1   3   7   2   6   4

得到索引数组后,根据索引数组对元素进行重排,由于index含义不同,重排算法也不同。下面直接给出两种索引排序代码,代码中有详细注释:

索引排序一

代码

#include<iostream>#include<iomanip>using namespace std;/*索引排序一index[i]是array[i]的最终下标*/void IndexSort1(int array[], int n){if (array && n > 1){//创建索引数组int *index = new int[n];//初始化索引数组int i, j;for (i = 0; i < n; i++)index[i] = i;//类似于插入排序,在插入比较的过程中不断地修改index数组for (i = 1; i < n; i++){j = i;while (j){if (array[i] < array[j-1]){index[i]--;index[j - 1]++;}j--;}}//打印索引数组cout << "索引数组" << endl;for (i = 0; i < n; i++)cout << setw(4) << index[i];cout << endl;//根据index数组,重排原序列bool modified = true;while (modified){modified = false;for (i = 0; i < n - 1; i++){//如果不在位置上,则调整if (index[i] != i){modified = true;j = index[i];swap(array[i], array[j]);index[i] = index[j];index[j] = j;}}}//释放空间delete[]index;}}//打印void print(int array[], int n){if(array && n>0){int i;for (i = 0; i < n; i++)cout << setw(4) << array[i];cout << endl;}}int main(){cout << "***索引排序***by David***\n";int array[] = {17, 19, 23, 21, 38, 5, 33, 22};int n = sizeof(array) / sizeof(array[0]);cout << "原序列\n";print(array, n);cout << "索引排序一" << endl;IndexSort1(array, n);cout << "排序后" << endl;print(array, n);system("pause");return 0;}

运行


 

索引排序二

代码

#include<iostream>#include<iomanip>using namespace std;/*索引排序二index[i]是array[i]中应该放置数据的下标*/void IndexSort2(int array[], int n){if (array && n > 1){//创建索引数组int *index = new int[n];//初始化索引数组int i, j;for (i = 0; i < n; i++)index[i] = i;//类似于插入排序,在插入比较的过程中不断地修改index数组for (i = 0; i < n; i++){j = i;while (j){if (array[index[j]] < array[index[j - 1]])swap(index[j], index[j - 1]);elsebreak;j--;}}//打印索引数组cout << "索引数组" << endl;for (i = 0; i < n; i++)cout << setw(4) << index[i];cout << endl;//元素重排int temp, k;for (i = 0; i < n; i++){j = i;temp = array[i];while (index[j] != i){k = index[j];array[j] = array[k];index[j] = j;j = k;}array[j] = temp;index[j] = j;}//释放空间delete[]index;}}//打印void print(int array[], int n){if(array && n>0){int i;for (i = 0; i < n; i++)cout << setw(4) << array[i];cout << endl;}}int main(){cout << "***索引排序***by David***\n";int array[] = {17, 19, 23, 21, 38, 5, 33, 22};int n = sizeof(array) / sizeof(array[0]);cout << "原序列\n";print(array, n);cout << "索引排序二" << endl;IndexSort2(array, n);cout << "排序后" << endl;print(array, n);system("pause");return 0;}

元素重排算法的详细解释

/*元素重排看似两重循环,则实际上的时间复杂度是线性的:O(n)一般情况下,经过一次while循环,将有多个元素归位*/int temp, k;for (i = 0; i < n; i++){/*加了这个判断后,while循环的后两条语句的执行得到优化:当元素已在正确的位置,则不需回填*/      if (index[i] != i){//以下的做法类似于“挖坑填数”j = i;temp = array[i];while (index[j] != i){k = index[j];//元素归位array[j] = array[k];//索引归位index[j] = j;//新的坑j = k;}//元素归位array[j] = temp;//索引归位index[j] = j;}}

运行


    

转载请注明出处,本文地址:http://blog.csdn.net/zhangxiangdavaid/article/details/37889669


若有所帮助,顶一个哦!


专栏目录:

  • 数据结构与算法
  • c指针


4 0