【Algorithm】基数排序
一. 算法描述
基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为三个过程:
- 分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
- 收集,再将放置在0~9号桶中的数据按顺序放到数组中
- 重复(1)(2)过程,从个位到最高位(比如32位无符号整形最大数4294967296,最高位10位)
下面以【521 310 72 373 15 546 385 856 187 147】序列为例,具体细节如下图所示:
二. 算法实现
#include<stdio.h> #define MAX 20 #define SHOWPASS #define BASE 10 // 打印数组 void print(int *a, int n) { int i; for (i = 0; i < n; i++) { printf("%d\t", a[i]); } } // 基数排序 void radixsort(int *a, int n) { int i, b[MAX], m = a[0], exp = 1; // 得到数组的最大值 for (i = 1; i < n; i++) { if (a[i] > m) { m = a[i]; } } while (m / exp > 0) { int bucket[BASE] = { 0 }; for (i = 0; i < n; i++) { bucket[(a[i] / exp) % BASE]++; } for (i = 1; i < BASE; i++) { bucket[i] += bucket[i - 1]; } for (i = n - 1; i >= 0; i--) { b[--bucket[(a[i] / exp) % BASE]] = a[i]; } for (i = 0; i < n; i++) { a[i] = b[i]; } exp *= BASE; #ifdef SHOWPASS printf("\nPASS : "); print(a, n); #endif } } int main() { int arr[MAX]; int i, n; printf("请输入总元素数目 (n <= %d) : ", MAX); scanf("%d", &n); n = n < MAX ? n : MAX; printf("请输入 %d 个元素 : \n", n); for (i = 0; i < n; i++) { scanf("%d", &arr[i]); } printf("\n排序前 : "); print(&arr[0], n); radixsort(&arr[0], n); printf("\n排序之后 : "); print(&arr[0], n); printf("\n"); return 0; }
三. 算法分析
- 平均时间复杂度:O(dn)(d即表示整形的最高位数)
- 空间复杂度:O(rn) (r表示0~9,用于存储临时的序列)
- 稳定性:稳定
参考资料
[1] http://blog.csdn.net/cjf_iceking/article/details/7943609
[2] http://zh.wikipedia.org/wiki/%E5%9F%BA%E6%95%B0%E6%8E%92%E5%BA%8F