码迷,mamicode.com
首页 > 编程语言 > 详细

基数排序

时间:2015-09-04 15:36:08      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

第一步

以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
这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。
LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行分配,但在分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。

实现方法

最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。
最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

实现原理

基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献。它是这样实现的:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
基数排序的方式可以采用LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。

 

技术分享
 1 #include<math.h>
 2 testBS()
 3 {
 4     inta[] = {2, 343, 342, 1, 123, 43, 4343, 433, 687, 654, 3};
 5     int *a_p = a;
 6     //计算数组长度
 7     intsize = sizeof(a) / sizeof(int);
 8     //基数排序
 9     bucketSort3(a_p, size);
10     //打印排序后结果
11     inti;
12     for(i = 0; i < size; i++)
13     {
14         printf("%d\n", a[i]);
15     }
16     intt;
17     scanf("%d", t);
18 }
19 //基数排序
20 voidbucketSort3(int *p, intn)
21 {
22     //获取数组中的最大数
23     intmaxNum = findMaxNum(p, n);
24     //获取最大数的位数,次数也是再分配的次数。
25     intloopTimes = getLoopTimes(maxNum);
26     inti;
27     //对每一位进行桶分配
28     for(i = 1; i <= loopTimes; i++)
29     {
30         sort2(p, n, i);
31     }
32 }
33 //获取数字的位数
34 intgetLoopTimes(intnum)
35 {
36     intcount = 1;
37     inttemp = num / 10;
38     while(temp != 0)
39     {
40         count++;
41         temp = temp / 10;
42     }
43     returncount;
44 }
45 //查询数组中的最大数
46 intfindMaxNum(int *p, intn)
47 {
48     inti;
49     intmax = 0;
50     for(i = 0; i < n; i++)
51     {
52         if(*(p + i) > max)
53         {
54             max = *(p + i);
55         }
56     }
57     returnmax;
58 }
59 //将数字分配到各自的桶中,然后按照桶的顺序输出排序结果
60 voidsort2(int *p, intn, intloop)
61 {
62     //建立一组桶此处的20是预设的根据实际数情况修改
63     intbuckets[10][20] = {};
64     //求桶的index的除数
65     //如798个位桶index=(798/1)%10=8
66     //十位桶index=(798/10)%10=9
67     //百位桶index=(798/100)%10=7
68     //tempNum为上式中的1、10、100
69     inttempNum = (int)pow(10, loop - 1);
70     inti, j;
71     for(i = 0; i < n; i++)
72     {
73         introw_index = (*(p + i) / tempNum) % 10;
74         for(j = 0; j < 20; j++)
75         {
76             if(buckets[row_index][j] == NULL)
77             {
78                 buckets[row_index][j] = *(p + i);
79                 break;
80             }
81         }
82     }
83     //将桶中的数,倒回到原有数组中
84     intk = 0;
85     for(i = 0; i < 10; i++)
86     {
87         for(j = 0; j < 20; j++)
88         {
89             if(buckets[i][j] != NULL)
90             {
91                 *(p + k) = buckets[i][j];
92                 buckets[i][j] = NULL;
93                 k++;
94             }
95         }
96     }
97 }
View Code

 

基数排序

标签:

原文地址:http://www.cnblogs.com/wangmengmeng/p/4781683.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!