基数排序属于分配式排序,它是透过键值的部分资讯,将要排序的元素分配到某些“桶”中,打到排序的作用,基数排序属于稳定性的排序。
对于基数排序有两种实现方法:最高位优先(即MSD法):先将k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成自组,之后的关键码也如此操作,直到kd。在将各组连接起来,就得到一个有序序列。
最低位优先(即LSD法):先从kd开始排序,在对kd-1排序,直到对k1排序,最后将各组连接起来,得到一个有序序列。
LSD(实现过程):
73, 22, 93, 43, 55, 14, 28, 65, 39, 81
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:
0
1 81
2 22
3 73 93 43
4 14
5 55 65
6
7
8 28
9 39
第二步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
81, 22, 73, 93, 43, 14, 55, 65, 28, 39
接着再进行一次分配,这次是根据十位数来分配:
0
1 14
2 22 28
3 39
4 43
5 55
6 65
7 73
8 81
9 93
第三步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
14, 22, 28, 39, 43, 55, 65, 73, 81, 93
这样便将这个数组中的元素排序了。
具体实现的代码如下:
#include<iostream>
using namespace std;
const int MAXSIZE = 10; //数组的长度
int main()
{
int data[MAXSIZE] = {432, 123, 544, 235, 146, 665, 217, 903, 334, 864};
int _queue[MAXSIZE][MAXSIZE] = {0};
int order[MAXSIZE] = {0};
cout << "排序前数组的顺序:" << endl;
for(int i=0; i<MAXSIZE; i++)
cout << data[i] << " " ;
int n=1, lsd, flag = 1;
while(n <= 100) //100代表数据中最大元素的位数
{
for(int i=0; i<MAXSIZE; i++)
{
lsd = (data[i] / n) % 10;
_queue[lsd][order[lsd]++] = data[i];
}
n *= 10;
int k = 0;
cout << "\n\n第" << flag++ <<"趟分配和收集后的数据顺序为:" << endl;
for(int i=0; i<MAXSIZE; i++)
{
if(order[i] != 0)
{
for(int j=0;j<order[i];j++)
{
data[k] = _queue[i][j];
cout << data[k++] << " ";
}
}
order[i] = 0;
}
}
cout << "\n\nLSD基数排序之后的结果:" << endl;
for(int i=0;i<MAXSIZE;i++)
cout << data[i] << " " ;
cout << "\n" ;
return 0;
}
假设我们给定n个d位数,其中每一个数位有k个可能的取值。那么我们使用基数排序可以在O(d(n+k))内将这些数进行排序。