Skip to content

DS-07-07 基数排序

408 > ### 数据结构 > #### 基数排序(Radix Sort)


一、定位信息

维度内容
章节归属第7章 排序
知识单元编号DS-07-07
前置知识DS-07-01 排序基本概念(非比较类排序)
后续衔接DS-07-09 排序算法综合对比
考试大纲要求掌握基数排序的算法思想、实现及性能分析
预计学习时长35分钟

二、知识点讲解

1. 基本思想

基数排序(Radix Sort)是一种非比较类排序算法。其核心思想是:

按关键字的各个位(个位、十位、百位…)依次进行排序,从最低位到最高位(LSD)或从最高位到最低位(MSD),每一趟使用稳定的排序算法(通常用计数排序或桶排序)。

关键性质:每一趟的排序必须是稳定的,这样才能保证高位排序后,相同高位的元素内部仍保持低位排序的顺序。

2. LSD 基数排序(最低位优先)

LSD(Least Significant Digit first)是考试中最常考的方式:

  1. 先按个位排序
  2. 再按十位排序
  3. 再按百位排序
  4. ……
  5. 最后按最高位排序

每一趟使用稳定的分配-收集过程。

3. 分配-收集过程

假设关键字为 d 位 r 进制数(r 为基数,即桶的个数):

c
// 基数排序(LSD),对关键字为 d 位的 r 进制数排序
void RadixSort(ElementType A[], int n, int d, int r) {
    // A[0..n-1]:待排序数组
    // d:关键字位数(最大位数)
    // r:基数(桶的个数,十进制时 r=10)
    // 每一趟对第 k 位(k = 0, 1, ..., d-1)进行分配和收集

    // 创建 r 个桶(链表或队列)
    Queue bucket[r];
    for (int k = 0; k < d; k++) {  // 从最低位到最高位
        // 分配:将每个元素按第 k 位的值放入对应桶中
        for (int i = 0; i < n; i++) {
            int digit = GetDigit(A[i], k);  // 取第 k 位的值
            Enqueue(bucket[digit], A[i]);    // 放入对应桶
        }
        // 收集:按桶的顺序依次取出元素
        int idx = 0;
        for (int j = 0; j < r; j++) {
            while (!IsEmpty(bucket[j])) {
                A[idx++] = Dequeue(bucket[j]);
            }
        }
    }
}

4. 过程示例

对序列 (329, 457, 657, 839, 436, 720, 355) 进行 LSD 基数排序(r=10, d=3):

第 1 趟(个位)

  • 桶 0: 720
  • 桶 5: 355
  • 桶 6: 436
  • 桶 7: 457, 657
  • 桶 9: 329, 839
  • 收集后:[720, 355, 436, 457, 657, 329, 839]

第 2 趟(十位)

  • 桶 2: 329, 720
  • 桶 3: 436, 839
  • 桶 5: 355, 457, 657
  • 收集后:[329, 720, 436, 839, 355, 457, 657]

第 3 趟(百位)

  • 桶 3: 329, 355
  • 桶 4: 436, 457
  • 桶 6: 657
  • 桶 7: 720
  • 桶 8: 839
  • 收集后:[329, 355, 436, 457, 657, 720, 839]

排序完成!

5. 时间复杂度分析

方面复杂度说明
趟数dd 为关键字位数
每趟分配O(n)每个元素放入一个桶
每趟收集O(n + r)遍历所有桶取出元素
总时间O(d(n + r))d 趟 × 每趟 O(n + r)

当 d 为常数、r 为常数时,时间复杂度为 O(n),可以突破比较排序的 Ω(n log n) 下界。

关键条件

  • d(位数)和 r(基数)相对于 n 较小时,基数排序效率高
  • 当 d ≈ log_r(n) 时,O(d(n+r)) ≈ O(n log n),与比较排序相当

6. 空间复杂度

O(r + n) = O(n)(当 r 为常数时)

  • r 个桶,每个桶需要空间
  • 辅助数组

7. 稳定性

稳定。每一趟的分配-收集过程使用的是稳定排序(如计数排序),保证了相同关键字的相对顺序不变。

关键:基数排序的稳定性不是算法本身的特性,而是要求每一趟必须使用稳定排序。如果某一趟使用不稳定排序,基数排序的结果将出错。


8. LSD vs MSD 对比表

对比维度LSD(最低位优先)MSD(最高位优先)
排序方向个位 → 十位 → 百位 → …百位 → 十位 → 个位 → …
是否需要递归不需要需要(对每个桶递归)
实现复杂度简单复杂
适用场景定长关键字不等长关键字
408 考查频率高频低频

三、记忆辅助

  1. 基数排序 = 按位分配收集:像扑克牌按花色分堆,再按点数分堆,每次分堆都保持之前的顺序
  2. 稳定性是前提:每一趟必须用稳定排序,否则高位排序会破坏低位的顺序
  3. O(d(n+r)):d 是位数,r 是基数(桶数),n 是元素个数。当 d 和 r 为常数时就是 O(n)
  4. 突破下界的原因:基数排序不比较关键字,而是利用关键字的位信息直接分配,所以不受 Ω(n log n) 限制
  5. LSD 记忆:L = Least = 最低位,先排低位后排高位,像数字排序的自然直觉

四、例题精解

例题 1:基数排序过程模拟

题目:对序列 (278, 109, 638, 984, 525, 369, 721) 进行 LSD 基数排序(r=10),写出每一趟的结果。

第一步:审题 n=7,关键字为 3 位十进制数,需要进行 3 趟分配-收集。

第二步:逐趟模拟

初始序列:[278, 109, 638, 984, 525, 369, 721]

第 1 趟(个位)

  • 桶 1: 721
  • 桶 4: 984
  • 桶 5: 525
  • 桶 8: 278, 638
  • 桶 9: 109, 369
  • 收集后:[721, 984, 525, 278, 638, 109, 369]

第 2 趟(十位)

  • 桶 0: 109
  • 桶 2: 721, 525
  • 桶 3: 638
  • 桶 6: 369
  • 桶 7: 278
  • 桶 8: 984
  • 收集后:[109, 721, 525, 638, 369, 278, 984]

第 3 趟(百位)

  • 桶 1: 109
  • 桶 2: 278
  • 桶 3: 369
  • 桶 5: 525
  • 桶 6: 638
  • 桶 7: 721
  • 桶 9: 984
  • 收集后:[109, 278, 369, 525, 638, 721, 984]

第三步:解答 排序结果:[109, 278, 369, 525, 638, 721, 984]

第四步:总结 基数排序共需 d=3 趟,每趟的分配和收集各需 O(n+r) 时间。注意每趟收集后序列的顺序变化。


例题 2:基数排序的时间复杂度分析

题目:对 n=1000 个 5 位十进制数进行基数排序,使用 r=10 的桶。计算总比较次数并与快速排序对比。

第一步:审题 n=1000, d=5, r=10,计算基数排序的时间代价并与快排对比。

第二步:分析

基数排序:

  • 趟数:d = 5
  • 每趟时间:O(n + r) = O(1000 + 10) = O(1010)
  • 总时间:O(d × (n + r)) = O(5 × 1010) ≈ 5050 次操作

快速排序(平均):

  • 总时间:O(n log n) = O(1000 × 10) ≈ 10000 次操作

第三步:解答

  • 基数排序:约 5050 次操作
  • 快速排序:约 10000 次操作
  • 基数排序在此场景下更快

但需注意:基数排序需要 O(n+r) = O(1010) 的额外空间,且仅适用于关键字位数有限的情况。

第四步:总结 当关键字位数 d 较小、基数 r 不大时,基数排序可以比 O(n log n) 的比较排序更快。但当 d ≈ log n 时,优势消失。


五、考情分析

年份题型考点难度
中频选择题基数排序的时间复杂度★★☆
中频分析题基数排序的过程模拟★★★
低频选择题基数排序的稳定性条件★★☆

命题趋势

  • 基数排序考查频率中等,但属于常考知识点
  • 时间复杂度 O(d(n+r)) 的分析是选择题常考点
  • 与比较排序下界结合考查是常见模式

六、易错点

  1. 每一趟必须稳定:基数排序的前提是每趟分配-收集使用稳定排序。如果某一趟不稳定,整个排序结果错误
  2. LSD 方向:必须从最低位开始。如果从最高位开始(MSD),需要递归处理,逻辑完全不同
  3. 时间复杂度不是 O(n):只有当 d 和 r 为常数时才是 O(n)。一般情况是 O(d(n+r))
  4. 基数排序不是比较排序:它不通过比较关键字大小来排序,所以不受 Ω(n log n) 下界约束
  5. 桶的个数 r 的选择:r 太大则空间开销大,r 太小则趟数 d 增加。需要权衡

七、来源标注

  • 《数据结构(C语言版)》严蔚敏,第10.6节 基数排序
  • 《数据结构》王道考研,第7章 7.6节 基数排序
  • 408考试大纲:数据结构部分-基数排序
  • 《算法导论》Thomas H. Cormen,第8.3节 基数排序

考研全科复习资料 - 基于2026考研统考大纲