| 项目 | 值 |
|---|---|
| 主题 | 基数排序 |
| 核心概念 | 非比较的排序算法,属于分配排序。不通过比较关键字排序,而是通过分配与收集按位处理。 |
| 时间复杂度 | $O(d\times(n+r))$(最好 / 平均 / 最坏均相同) |
| 空间复杂度 | $O(n+r)$ |
| 稳定性 | ✅ 稳定(详见「稳定性分析」) |
| 难度 | ⭐⭐⭐ |
基数排序(Radix Sort)是一种非比较的排序算法,是分配排序的一种。它不通过比较关键字来排序,而是通过分配和收集的方式,按位对关键字进行排序。
// 基数排序(LSD,链式实现)
#define MAX_DIGIT 10 // 最大位数
#define RADIX 10 // 基数(十进制)
// 链表结点
typedef struct Node {
int data;
struct Node *next;
} Node;
// 获取整数 x 的第 d 位数字(从个位开始,d=0 表示个位)
int GetDigit(int x, int d) {
for (int i = 0; i < d; i++)
x /= 10;
return x % 10;
}
// 基数排序
void RadixSort(int A[], int n) {
// 创建 r 个队列(用链表实现)
Node *bucket[RADIX]; // 桶数组
Node *tail[RADIX]; // 每个桶的尾指针
// 计算最大位数 d
int maxVal = A[0];
for (int i = 1; i < n; i++)
if (A[i] > maxVal) maxVal = A[i];
int d = 0;
while (maxVal > 0) { d++; maxVal /= 10; }
// 创建链表
Node *head = (Node *)malloc(sizeof(Node));
head->next = NULL;
Node *p = head;
for (int i = 0; i < n; i++) {
p->next = (Node *)malloc(sizeof(Node));
p = p->next;
p->data = A[i];
p->next = NULL;
}
// LSD 基数排序
for (int i = 0; i < d; i++) {
// 初始化桶
for (int j = 0; j < RADIX; j++) {
bucket[j] = (Node *)malloc(sizeof(Node));
bucket[j]->next = NULL;
tail[j] = bucket[j];
}
// 分配
p = head->next;
while (p != NULL) {
int digit = GetDigit(p->data, i);
tail[digit]->next = p;
tail[digit] = p;
p = p->next;
}
tail[digit]->next = NULL; // 最后一个桶的尾部置空
// 收集
head->next = NULL;
p = head;
for (int j = 0; j < RADIX; j++) {
if (bucket[j]->next != NULL) {
p->next = bucket[j]->next;
p = tail[j];
}
free(bucket[j]);
}
p->next = NULL;
}
// 将排序结果写回数组
p = head->next;
for (int i = 0; i < n; i++) {
A[i] = p->data;
Node *temp = p;
p = p->next;
free(temp);
}
free(head);
}
next 置空,而不是只置空最后一次用到的桶。对序列 {329, 457, 657, 839, 436, 720, 355} 进行 LSD 基数排序。
初始:329, 457, 657, 839, 436, 720, 355
Q_0: 720
Q_1:
Q_2:
Q_3:
Q_4:
Q_5: 355
Q_6: 436
Q_7: 457, 657
Q_8:
Q_9: 329, 839
收集:720, 355, 436, 457, 657, 329, 839
Q_0:
Q_1:
Q_2: 720, 329
Q_3: 436, 839
Q_4:
Q_5: 355, 457, 657
Q_6:
Q_7:
Q_8:
Q_9:
收集:720, 329, 436, 839, 355, 457, 657
Q_0:
Q_1:
Q_2:
Q_3: 329, 355
Q_4: 436, 457
Q_5:
Q_6: 657
Q_7: 720
Q_8: 839
Q_9:
收集:329, 355, 436, 457, 657, 720, 839
最终结果:329, 355, 436, 457, 657, 720, 839
| 情况 | 时间复杂度 | 说明 |
|---|---|---|
| 最好情况 | $O(d\times(n+r))$ | 与初始序列无关 |
| 平均情况 | $O(d\times(n+r))$ | 与初始序列无关 |
| 最坏情况 | $O(d\times(n+r))$ | 与初始序列无关 |
空间复杂度为 $O(n+r)$。
原因:
(暂无关联知识点)
↑ 本页右上「在 Obsidian 中打开」可跳回源笔记。