基数排序:
基数排序的思想就是将待排数据中的每组关键字依次进行桶分配
基数排序:LSD和MSD方法。LSD的基数排序适用于位数小的数列,如果位数多,使用MSD效率会更高。
MSD与LSD相反,由高位数为基底开始分配。
LSD为例:73, 22, 93, 43, 55, 14, 28, 65, 39, 81
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中。
接下来将这些桶子中的数值重新串接起来,成为以下的数列:81, 22, 73, 93, 43, 14, 55, 65, 28, 39
接着再进行一次分配,这次是根据十位数来分配:
1 int maxbit(int data[], int n) //辅助函数,求数据的最大位数
2 {
3 int d = 1; //保存最大的位数
4 int p = 10;
5 for(int i = 0; i < n; ++i)
6 {
7 while(data[i] >= p)//复杂度(dN)
8 {
9 p *= 10;
10 ++d;
11 }
12 }
13 return d;
14 }
15
16 void radixsort(int data[], int n) //基数排序
17 {
18 int d = maxbit(data, n);//求得数组中所有的数据的最大位数
19 int *tmp = new int[n];//存放每一位基数排序的结果
20 int *count = new int[10]; //计数器
21 int i, j, k;
22 int radix = 1;//关键字
23 for(i = 1; i <= d; i++) //进行d次排序
24 {
25 for(j = 0; j < 10; j++)
26 count[j] = 0; //每次分配前清空计数器
27 for(j = 0; j < n; j++)
28 {
29 k = (data[j] / radix) % 10; //统计每个桶中的记录数
30 count[k]++;
31 }
32 for(j = 1; j < 10; j++)
33 count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶,为count[k]在tmp中预留位置。把桶累计起来。
34 for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
35 {
36 k = (data[j] / radix) % 10;
37 tmp[count[k] - 1] = data[j];//把桶串起来
38 count[k]--;
39 }
40 for(j = 0; j < n; j++) //将临时数组的内容复制到data中
41 data[j] = tmp[j];
42 radix = radix * 10;//每次更新关键字
43 }
44 delete[]tmp;
45 delete[]count;
46 }