代码:
#include <stdio.h>
#include <stdlib.h>
// 假设元素最多有 MaxDigit 个关键字, 基数全是同样的 Radix
#define MaxDigit 4
#define Radix 10
typedef int ElementType;
// 桶元素节点
typedef struct Node *PtrToNode;
struct Node
{
int key;
PtrToNode next;
};
// 桶头节点
struct HeadNode
{
PtrToNode head, tail;
};
typedef struct HeadNode Bucket[Radix];
// 默认次位 D = 1, 主位 D <= MaxDigit
int GetDigit(int X, int D)
{
int d, i;
for (i = 1; i <= D; i++)
{
d = X % Radix;
X /= Radix;
}
return d;
}
// 基数排序-次位优先
void LSDRadixSort(ElementType A[], int N)
{
int D, Di, i;
Bucket B;
PtrToNode tmp, p, List = NULL;
for (i = 0; i < Radix; i++) // 初始化每个桶为空链表
{
B[i].head = B[i].tail = NULL;
}
for (i = 0; i < N; i++) // 将原始序列逆序存入初始链表 List
{
tmp = (PtrToNode) malloc(sizeof(struct Node));
tmp->key = A[i];
tmp->next = List;
List = tmp;
}
// 下面开始排序
for (D = 1; D <= MaxDigit; D++) // 对数据的每一位循环处理
{
// 下面是分配的过程
p = List;
while (p)
{
Di = GetDigit(p->key, D); // 获得当前元素的当前位数字
// 从 List 中摘除
tmp = p;
p = p->next;
// 插入 B[i] 号桶尾
tmp->next = NULL;
if (B[Di].head == NULL)
B[Di].head = B[Di].tail = tmp;
else
{
B[Di].tail->next = tmp;
B[Di].tail = tmp;
}
}
// 下面是收集的过程
List = NULL;
for (Di = Radix - 1; Di >= 0; Di--) // 将每个桶的元素顺序收集入 List
{
if (B[Di].head) // 如果桶不为空
{
// 整桶插入 List 表头
B[Di].tail->next = List;
List = B[Di].head;
B[Di].head = B[Di].tail = NULL; // 清空桶
}
}
}
// 将 List 倒入 A[] 并释放空间
for (i = 0; i < N; i++)
{
tmp = List;
List = List->next;
A[i] = tmp->key;
free(tmp);
}
}
int main()
{
int A[12] = {93, 55, 25, 7, 51, 73, 72, 120, 131, 37, 27, 3};
LSDRadixSort(A, 12);
for (int i = 0; i < 12; ++i)
{
printf("%d ", A[i]);
}
return 0;
}
测试结果:
按 : 可以根据需要, 修改代码中的 Radix 值, 即修改基数.