1. 程式人生 > >基數排序C++實現

基數排序C++實現

基數排序介紹

基數排序(Radix Sort)是桶排序的擴充套件,它的基本思想是:將整數按位數切割成不同的數字,然後按每個位數分別比較。
具體做法是:將所有待比較數值統一為同樣的數位長度,數位較短的數前面補零。然後,從最低位開始,依次進行一次排序。這樣從最低位排序一直到最高位排序完成以後, 數列就變成一個有序序列。

基數排序圖文說明

基數排序圖文說明

通過基數排序對陣列{53, 3, 542, 748, 14, 214, 154, 63, 616},它的示意圖如下:

在上圖中,首先將所有待比較樹脂統一為統一位數長度,接著從最低位開始,依次進行排序。
1. 按照個位數進行排序。
2. 按照十位數進行排序。
3. 按照百位數進行排序。
排序後,數列就變成了一個有序序列。

為什麼要從個數開始比較,低位是有序的,高位中如果有相同的值,則只需在保持穩定的前提下對高位進行排序,結果自然有序。

基數排序程式碼

//radix sort
//基數排序也是基於一種假設,假設所有數都是非負的整數
//基數排序的基本思路是從低位至高位依次比較每個數的對應位,並排序;對應位的比較採用計數排序也可以採用桶排序;
//基數排序是一種穩定的排序方法,不穩定的話也沒法排序,因為某一位相同並不代表兩個數相同;


#include<iostream>
#include<vector>

using namespace std;

void countSort(vector<int>& vec,int exp)
{//計數排序
	vector<int> range(10,0);

	int length=vec.size();
	vector<int> tmpVec(length,0);

	for(int i=0;i<length;++i)
	{
		range[(vec[i]/exp)%10]++;
	}

	for(int i=1;i<range.size();++i)
	{
		range[i]+=range[i-1];//統計本應該出現的位置
	}

	for(int i=length-1;i>=0;--i)
	{
		tmpVec[range[(vec[i]/exp)%10]-1]=vec[i];
		range[(vec[i]/exp)%10]--;
	}
	vec=tmpVec;
}

void radixSort(vector<int>& vec)
{
	int length=vec.size();
	int max=-1;
	for(int i=0;i<length;++i)
	{//提取出最大值
		if(vec[i]>max)
			max=vec[i];
	}
	
	//提取每一位並進行比較,位數不足的高位補0
	for(int exp=1;max/exp>0;exp*=10)
		countSort(vec,exp);
}

int main()
{
	int a[10]={53,3,542,748,14,214,154,63,616,589};

	vector<int> vec(a,a+10);
	radixSort(vec);

	for(int i=0;i<vec.size();++i)
	{
		cout<<vec[i]<<"   ";
	}
	
	cout<<endl;
	return 0;
}


radixSort(a, n)的作用是對陣列a進行排序。
1. 首先獲取最大值,目的是計算出陣列a的最大指數。獲取到陣列a中的最大指數之後,再從指數1開始,根據位數對陣列a中的元素進行排序。排序的時候採用了計數排序。

2.countSort(vec, exp)的作用是對陣列a按照指數exp進行排序。

下面簡單介紹一下對陣列{53, 3, 542, 748, 14, 214, 154, 63, 616}按個位數進行排序的流程。

       a、個位的數值範圍是[0,10)。因此,參見陣列ranges,range[i]代表i之前的資料出現次數,也即當前數本應該在的位置。

      b、 接著是根據陣列range來進行排序。假設將排序後的陣列存在tmpVec中;找出tmpVec和range之間的聯絡就可以對資料進行排序了

參考文章:http://blog.csdn.net/coslay/article/details/47806035