十大经典排序算法(十、基数排序)

动图演示

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。

基数排序有两种方法:

这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

  • 基数排序:根据键值的每位数字来分配桶;
  • 计数排序:每个桶只存储单一键值;
  • 桶排序:每个桶存储一定范围的数值;

JavaScript

 1 ar counter = [];
 2 function radixSort(arr, maxDigit) {
 3     var mod = 10;
 4     var dev = 1;
 5     for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
 6         for(var j = 0; j < arr.length; j++) {
 7             var bucket = parseInt((arr[j] % mod) / dev);
 8             if(counter[bucket]==null) {
 9                 counter[bucket] = [];
10             }
11             counter[bucket].push(arr[j]);
12         }
13         var pos = 0;
14         for(var j = 0; j < counter.length; j++) {
15             var value = null;
16             if(counter[j]!=null) {
17                 while ((value = counter[j].shift()) != null) {
18                       arr[pos++] = value;
19                 }
20           }
21         }
22     }
23     return arr;
24 }

C语言

 1 #include<stdio.h>
 2 #define MAX 20
 3 //#define SHOWPASS
 4 #define BASE 10
 5 
 6 void print(int *a, int n) {
 7   int i;
 8   for (i = 0; i < n; i++) {
 9     printf("%d\t", a[i]);
10   }
11 }
12 
13 void radixsort(int *a, int n) {
14   int i, b[MAX], m = a[0], exp = 1;
15 
16   for (i = 1; i < n; i++) {
17     if (a[i] > m) {
18       m = a[i];
19     }
20   }
21 
22   while (m / exp > 0) {
23     int bucket[BASE] = { 0 };
24 
25     for (i = 0; i < n; i++) {
26       bucket[(a[i] / exp) % BASE]++;
27     }
28 
29     for (i = 1; i < BASE; i++) {
30       bucket[i] += bucket[i - 1];
31     }
32 
33     for (i = n - 1; i >= 0; i--) {
34       b[--bucket[(a[i] / exp) % BASE]] = a[i];
35     }
36 
37     for (i = 0; i < n; i++) {
38       a[i] = b[i];
39     }
40 
41     exp *= BASE;
42 
43 #ifdef SHOWPASS
44     printf("\nPASS   : ");
45     print(a, n);
46 #endif
47   }
48 }
49 
50 int main() {
51   int arr[MAX];
52   int i, n;
53 
54   printf("Enter total elements (n <= %d) : ", MAX);
55   scanf("%d", &n);
56   n = n < MAX ? n : MAX;
57 
58   printf("Enter %d Elements : ", n);
59   for (i = 0; i < n; i++) {
60     scanf("%d", &arr[i]);
61   }
62 
63   printf("\nARRAY  : ");
64   print(&arr[0], n);
65 
66   radixsort(&arr[0], n);
67 
68   printf("\nSORTED : ");
69   print(&arr[0], n);
70   printf("\n");
71 
72   return 0;
73 }

C++

 1 int maxbit(int data[], int n) //辅助函数,求数据的最大位数
 2 {
 3     int maxData = data[0];              ///< 最大数
 4     /// 先求出最大数,再求其位数,这样有原先依次每个数判断其位数,稍微优化点。
 5     for (int i = 1; i < n; ++i)
 6     {
 7         if (maxData < data[i])
 8             maxData = data[i];
 9     }
10     int d = 1;
11     int p = 10;
12     while (maxData >= p)
13     {
14         //p *= 10; // Maybe overflow
15         maxData /= 10;
16         ++d;
17     }
18     return d;
19 /*    int d = 1; //保存最大的位数
20     int p = 10;
21     for(int i = 0; i < n; ++i)
22     {
23         while(data[i] >= p)
24         {
25             p *= 10;
26             ++d;
27         }
28     }
29     return d;*/
30 }
31 void radixsort(int data[], int n) //基数排序
32 {
33     int d = maxbit(data, n);
34     int *tmp = new int[n];
35     int *count = new int[10]; //计数器
36     int i, j, k;
37     int radix = 1;
38     for(i = 1; i <= d; i++) //进行d次排序
39     {
40         for(j = 0; j < 10; j++)
41             count[j] = 0; //每次分配前清空计数器
42         for(j = 0; j < n; j++)
43         {
44             k = (data[j] / radix) % 10; //统计每个桶中的记录数
45             count[k]++;
46         }
47         for(j = 1; j < 10; j++)
48             count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶
49         for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
50         {
51             k = (data[j] / radix) % 10;
52             tmp[count[k] - 1] = data[j];
53             count[k]--;
54         }
55         for(j = 0; j < n; j++) //将临时数组的内容复制到data中
56             data[j] = tmp[j];
57         radix = radix * 10;
58     }
59     delete []tmp;
60     delete []count;
61 }

 

posted @ 2020-12-29 13:41  梓涵VV  阅读(119)  评论(0编辑  收藏  举报