基数排序
基数排序又称为桶排序,是一种非比较型整数排序算法。基数排序与本系列前面讲解的七种排序方法都不同,它不需要比较关键字的大小。它是根据关键字中各位的值,通过对排序的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 }