索引排序
来源:互联网 发布:网吧网络组建方案 编辑:程序博客网 时间: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
- 索引排序
- 索引排序
- 索引排序
- 索引排序
- 索引排序
- 序列数索引(排序索引)
- MySQL 文件排序 &索引排序
- 排序专题之索引排序
- 数组索引排序
- 索引排序顺序
- Lucene 的索引排序
- SQL索引排序
- mapreduce倒排序索引
- 【索引】排序与检索
- mapreduce倒排序索引
- 算法与排序--索引
- 索引与排序
- 倒排序索引
- Netstat命令详解
- 数据结构学习笔记6-图
- jstl中的if else
- 寄存器,verilog 中 reg
- XCode6中显示行号设置
- 索引排序
- 黑马程序员--学习日记(八)高新部分java基础加强(一)
- Win8.1应用开发之动态磁贴
- 《推荐系统实践》读书笔记——第四章
- 为什么在Outlook中Ctrl+F代表转发而不是查找
- Linux中搭建memcached,并为php安装memcache扩展
- jstl获取值的方法
- Angular JS解析(二)——解析一个APP
- Cocos2d-x 3.0坐标系详解---------------------cocos2d-x3.0正式版本(7.16)