一.原理
所谓的基数排序的基数
,就是我们讲进制
时候的那个基数。比如十进制的基数就是10,二进制的基数就是2。其中,从右向左开始第n位,实际上表示的是基数的n次方倍。比如1012表示 1 ⋅ 2 0 + 0 ⋅ 2 1 + 1 ⋅ 2 2 1\cdot2^0+0\cdot2^1+1\cdot2^2 1⋅20+0⋅21+1⋅22
那么,我们可以通过先比较某一位,进行排序,然后再比较另一位进行排序,直到排完所有的位数。比如我们以LSD低位优先法
,从右往左一位一位的比较;或者MSD高位优先法
,从左到右一位一位的比较,从左往右一位一位的比较。
过程:
- 创建基数个队列,下标从0开始。
- 取关键字某位的值,存入对应编号的队列(有点像哈希表)
- 从0或者从基数-1的队列开始,递增或递减出队,这样出队构成的顺序表、链表是某位有序的。
- 重复更改位数,并2、3,直到所有位都有序,最后出队的队列就有序。
二.过程
一般我们用的都是10进制,所以采取基数为10更直观。
假设我们对这些数以低位优先的方式排序:
对低位进行排序:
对次低位排序:
再次低位:
这样就拍好了。
三.代码
代码很很很简单,所以就不想写了,抄个代码,菜鸟教程 1.10 基数排序:
#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("Enter total elements (n <= %d) : ", MAX);
scanf("%d", &n);
n = n < MAX ? n : MAX;
printf("Enter %d Elements : ", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
printf("\nARRAY : ");
print(&arr[0], n);
radixsort(&arr[0], n);
printf("\nSORTED : ");
print(&arr[0], n);
printf("\n");
return 0;
}