基数排序

基数排序又称为桶排序,是一种非比较型整数排序算法。基数排序与本系列前面讲解的七种排序方法都不同,它不需要比较关键字的大小。它是根据关键字中各位的值,通过对排序的N个元素进行若干趟“分配”与“收集”来实现排序的。

当然,这个算法思想比较好理解。但是要实现一个桶结构还是比较麻烦,因此有人通过巧妙的设计来简化了数据结构,同时也节省了空间,具体代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int max_bit(int a[], int n)//辅助函数,求数据的最大位数
 5 {
 6     int digits = 1;//保存最大的位数
 7     int i, p = 10;
 8 
 9     for (i = 0; i < n; i++){
10         while (a[i] >= p){
11             p *= 10;
12             digits++;//位数加1
13         }
14     }
15     return digits;
16 }
17 
18 void radix_sort(int a[], int left, int right)
19 {
20     int length = right - left + 1;  //排序数组长度
21     int digits = max_bit(a, length);//数据最大位数
22     int i, j, k, radix = 1;
23     int cnt[10];//计数器,记录每个桶中元素的个数
24     int *tmp =  (int *)malloc(length * sizeof(int));
25     //进行digits次排序
26     for (i = 1; i <= digits; i++){
27         //每次分配前情况计数器
28         for (j = 0; j < 10; j++){
29             cnt[j] = 0;
30         }
31         //统计每个桶中的记录个数
32         for (j = left; j <= right; j++){
33             k = (a[j] / radix) % 10;
34             cnt[k]++;
35         }
36         //将tmp中的位置依次分配给每个桶
37         for (j = 1; j < 10; j++){
38             cnt[j] = cnt[j-1] + cnt[j];//cnt[]中存储每个桶中末尾元素的下标
39         }
40         //将所有桶中记录收集到tmp中(从后往前)
41         for (j = length - 1; j >= 0; j--){
42             k = (a[j] / radix) % 10;
43             tmp[cnt[k] - 1] = a[j];
44             cnt[k]--;// 第k个桶的下一个存储位置
45         }
46         //将临时数组中的内容复制到原始数组中
47         printf("radix %4d : ", radix);
48         for (j = 0; j < length; j++){
49             a[j] = tmp[j];
50             printf("%4d ", a[j]);
51         }
52         printf("\n");
53 
54 
55         radix = 10 * radix;
56     }
57     free(tmp);
58 }
59 
60 
61 int main()
62 {
63     int a[] = {50,123,543,187,49,30,0,2,11,100};
64 
65     radix_sort(a, 0, 9);
66     
67     return 0;
68 }

 

posted @ 2015-08-13 10:42  XiaoManon  阅读(315)  评论(0编辑  收藏  举报