zoukankan      html  css  js  c++  java
  • 索引排序

    索引排序

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

    索引含义

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

    一、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***
    ";
    	int array[] = {17, 19, 23, 21, 38, 5, 33, 22};
    	int n = sizeof(array) / sizeof(array[0]);
    	cout << "原序列
    ";
    	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]);
    				else
    					break;
    				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***
    ";
    	int array[] = {17, 19, 23, 21, 38, 5, 33, 22};
    	int n = sizeof(array) / sizeof(array[0]);
    	cout << "原序列
    ";
    	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


    若有所帮助。顶一个哦。


    专栏文件夹:


  • 相关阅读:
    Storm 中drpc调用
    yarn下资源配置
    java 中 Stringbuff append源代码浅析
    总结的MR中连接操作
    hive中使用rcfile
    MapFile
    HDFS副本存放读取
    zoj 1967 Fiber Network/poj 2570
    zoj 2027 Travelling Fee
    poj 1742 Coins
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6784846.html
Copyright © 2011-2022 走看看