【数据结构】排序算法:归并排序与基数排序

考点频率 :★★★★☆(选择题常考,归并排序的复杂度与稳定性是重点,基数排序常考其适用场景)

难度 :⭐⭐⭐⭐(归并排序需理解分治与合并,基数排序需理解分配与收集过程)

建议:重点掌握归并排序的"分治+合并"思想及时间复杂度;重点掌握基数排序的LSD过程及适用场景

1️⃣ 为什么还有这两种排序?

前面我们学过了插入类(插入排序)、交换类(冒泡、快速)、选择类(简单选择、堆排序)。这些排序算法有一个共同特点:它们都基于"比较"------通过比较元素的大小来决定位置。

而归并排序和基数排序代表了两种完全不同的思路:

算法 核心策略 一句话概括
归并排序 分治:先分割成小块,排序后再合并 "先分后合,分而治之"
基数排序 不比较大小,按位分配 "按位分配,逐位收集"

打个比方 :归并排序像整理一份打乱的文件 ------先把文件分成两半,分别整理好,再把两半合并成一份有序的整体。基数排序像按电话号码排序------先按最后一位分到10个桶里,再按倒数第二位分......经过所有位数后自然就有序了,全程不需要比较大小。

2️⃣ 归并排序(Merge Sort)

2.1 核心思想

归并排序采用分治(Divide and Conquer) 策略:

  1. :将待排序序列从中间一分为二,递归地对左右两部分进行归并排序
  2. :当子序列长度为1时,递归返回
  3. :将两个已排序的子序列合并成一个有序序列

打个比方:你有一副打乱顺序的扑克牌。你把牌分成两堆,分别整理成有序的,然后再把两堆牌合并成一堆有序的牌。这个过程就像"分而治之"------先分后合。

2.2 合并两个有序数组(核心操作)

归并排序的核心操作是合并两个已经有序的子序列

复制代码
左子序列: [1, 3, 5, 7]
右子序列: [2, 4, 6, 8]

合并过程:
1. 比较1和2 → 取1
2. 比较3和2 → 取2
3. 比较3和4 → 取3
4. 比较5和4 → 取4
5. 比较5和6 → 取5
6. 比较7和6 → 取6
7. 比较7和8 → 取7
8. 取8

合并结果: [1, 2, 3, 4, 5, 6, 7, 8]

2.3 执行过程示例

对数组 [5, 3, 8, 1, 4, 7, 2, 6] 进行归并排序:

复制代码
                    [5, 3, 8, 1, 4, 7, 2, 6]
                          /             \
                   [5, 3, 8, 1]       [4, 7, 2, 6]
                    /        \         /        \
               [5, 3]      [8, 1]   [4, 7]    [2, 6]
               /   \       /   \    /   \     /   \
             [5]   [3]   [8]  [1]  [4]  [7]  [2]  [6]
              \    /      \   /     \   /     \   /
              [3, 5]      [1, 8]   [4, 7]    [2, 6]
                \          /         \        /
              [1, 3, 5, 8]          [2, 4, 6, 7]
                   \                    /
                  [1, 2, 3, 4, 5, 6, 7, 8]

2.4 复杂度与特点

情况 时间复杂度 说明
最好情况 O(nlog⁡n)O(n \log n)O(nlogn) 与初始顺序无关
最坏情况 O(nlog⁡n)O(n \log n)O(nlogn) 与初始顺序无关
平均情况 O(nlog⁡n)O(n \log n)O(nlogn) 与初始顺序无关

空间复杂度 :O(n)O(n)O(n)(合并时需要额外的数组空间)

稳定性 :✅ 稳定(合并时相等元素保持原有顺序)

3️⃣ 基数排序(Radix Sort)

3.1 核心思想

基数排序不基于比较 ,而是基于分配和收集。它将整数按位数(个位、十位、百位......)进行多趟排序。

打个比方:你要按学号给同学排序。你不需要比较学号的大小,而是先按最后一位数字分到10个组里(分配),按顺序收集起来(收集);再按倒数第二位数字分组收集......经过所有位数后,学号自然就有序了。

两种实现方式

方式 说明 软考重点
最高位优先(MSD) 从最高位开始分配 较少考查
最低位优先(LSD) 从最低位开始分配 软考重点

LSD的实现更简单,也是软考中最常考的方式。

3.2 基数排序的LSD过程

步骤

  1. 确定最大数的位数 ddd
  2. 对 i=0i = 0i=0 到 d−1d-1d−1:
    • 分配 :根据第 iii 位的数字(0-9),将元素放入对应的10个桶中
    • 收集:按桶的顺序(0→1→2→...→9)依次取出元素

示例 :对 [329, 457, 657, 839, 436, 720, 355] 进行基数排序(LSD)

第1趟(按个位分配)

桶0 桶1 桶2 桶3 桶4 桶5 桶6 桶7 桶8 桶9
720 --- --- --- --- 355 436 457,657 --- 329,839

收集后:[720, 355, 436, 457, 657, 329, 839]

第2趟(按十位分配)

桶0 桶1 桶2 桶3 桶4 桶5 桶6 桶7 桶8 桶9
--- --- 329 436 --- 457,657 --- --- --- ---
720 --- --- --- 839 --- --- --- --- ---

收集后:[720, 329, 436, 839, 355, 457, 657]

第3趟(按百位分配)

桶0 桶1 桶2 桶3 桶4 桶5 桶6 桶7 桶8 桶9
--- --- --- 329,355 436,457 --- 657 720 --- ---

收集后:[329, 355, 436, 457, 657, 720, 839]

3.3 复杂度与特点

情况 时间复杂度 说明
最好情况 O(d×(n+r))O(d \times (n + r))O(d×(n+r)) ddd 为位数,rrr 为基数(通常为10)
最坏情况 O(d×(n+r))O(d \times (n + r))O(d×(n+r)) 与初始顺序无关
平均情况 O(d×(n+r))O(d \times (n + r))O(d×(n+r)) 与初始顺序无关

空间复杂度 :O(n+r)O(n + r)O(n+r)(需要桶的空间)

稳定性 :✅ 稳定(分配收集不改变同值元素的顺序)

关键特点

  • 基数排序的复杂度与初始序列是否有序无关
  • 适用于整数、字符串等固定位数的数据
  • 当 ddd 较小时效率很高(如身份证号、学号)

4️⃣ 八大排序算法全景对比(必背总结表)

算法 最好 最坏 平均 空间 稳定性 是否原地
插入排序 O(n)O(n)O(n) O(n2)O(n^2)O(n2) O(n2)O(n^2)O(n2) O(1)O(1)O(1) ✅ 稳定 ✅ 是
冒泡排序 O(n)O(n)O(n) O(n2)O(n^2)O(n2) O(n2)O(n^2)O(n2) O(1)O(1)O(1) ✅ 稳定 ✅ 是
简单选择 O(n2)O(n^2)O(n2) O(n2)O(n^2)O(n2) O(n2)O(n^2)O(n2) O(1)O(1)O(1) ❌ 不稳定 ✅ 是
快速排序 O(nlog⁡n)O(n \log n)O(nlogn) O(n2)O(n^2)O(n2) O(nlog⁡n)O(n \log n)O(nlogn) O(log⁡n)O(\log n)O(logn) ❌ 不稳定 ✅ 是
堆排序 O(nlog⁡n)O(n \log n)O(nlogn) O(nlog⁡n)O(n \log n)O(nlogn) O(nlog⁡n)O(n \log n)O(nlogn) O(1)O(1)O(1) ❌ 不稳定 ✅ 是
归并排序 O(nlog⁡n)O(n \log n)O(nlogn) O(nlog⁡n)O(n \log n)O(nlogn) O(nlog⁡n)O(n \log n)O(nlogn) O(n)O(n)O(n) ✅ 稳定 ❌ 否
希尔排序 O(n1.3)O(n^{1.3})O(n1.3) O(n2)O(n^2)O(n2) O(nlog⁡n)O(n \log n)O(nlogn)~O(n2)O(n^2)O(n2) O(1)O(1)O(1) ❌ 不稳定 ✅ 是
基数排序 O(d(n+r))O(d(n+r))O(d(n+r)) O(d(n+r))O(d(n+r))O(d(n+r)) O(d(n+r))O(d(n+r))O(d(n+r)) O(n+r)O(n+r)O(n+r) ✅ 稳定 ❌ 否

5️⃣ 经典例题

例题1 (归并排序过程):对序列 [6, 2, 8, 1, 5, 3] 进行归并排序,写出第一次合并后的结果。

解析

  • 分:[6, 2, 8][1, 5, 3]
  • 继续分:[6] [2, 8][1] [5, 3]
  • 继续分:[6] [2] [8][1] [5] [3]
  • 合并相邻:[2, 6] [1, 8][1, 5] [3]
  • 再合并:[1, 2, 6, 8][1, 3, 5]
  • 最终合并:[1, 1, 2, 3, 5, 6, 8]

第一次合并后的结果是 [2, 6] [1, 8] [1, 5] [3]

答案[2, 6, 1, 8, 1, 5, 3]


例题2(基数排序适用场景):以下哪种数据最适合用基数排序?

A. 100个随机浮点数

B. 10000个学生的学号(8位数字)

C. 10000个随机字符串(长度不等)

D. 100个结构体对象

解析 :基数排序适合固定长度 的数据(如学号、身份证号、IP地址)。A浮点数处理复杂;C长度不等需要特殊处理;D结构体需按特定关键字排序。B学号是固定8位数字,最适合基数排序。选 B


例题3 (判断):归并排序的平均时间复杂度为 O(n2)O(n^2)O(n2)。( )

解析 :错误。归并排序的平均时间复杂度为 O(nlog⁡n)O(n \log n)O(nlogn)。

6️⃣ 记忆口诀

归并排序分治精,先分后合两路行。

O(nlog⁡n)O(n \log n)O(nlogn) 稳定排,空间 O(n)O(n)O(n) 要记清。

基数排序不比较,按位分配逐位收。

ddd 趟收集 n+rn+rn+r,固定长度最优解。

7️⃣ 小测验(评论区对答案)

对序列 [4, 2, 7, 1, 9, 5] 进行归并排序,合并过程中最后一轮合并时,左右两个子序列分别是( )。

A. [2, 4, 7][1, 5, 9]

B. [1, 2, 4, 7][5, 9]

C. [2, 4, 7][1, 5, 9]

D. [1, 2, 4, 5, 7, 9]

🔔 本专栏日更,点击头像 → 专栏《软考中级高频考点》订阅,第一时间接收新内容

#软考中级 #软件设计师 #归并排序 #基数排序 #排序算法 #数据结构 #软考备考

相关推荐
吃旺旺雪饼的小男孩1 小时前
U-Net 语义分割详解:原论文、PyTorch 实现与真实消融实
人工智能·pytorch·python·算法
lucas_AI1 小时前
35 种开源文档抽取配置,只有 4 个跨过 F1 0.5
人工智能·算法·llm
练习时长一年的RL研究者2 小时前
与AI对话后对 Actor-Critic 中 TD Target 的 a‘ 来源总结
算法
大熊背2 小时前
ISP图像处理中大数乘法溢出处理(二)
算法·大数乘法
LuminousCPP2 小时前
嵌入式-51单片机入门(三)-数码管驱动:从单管点亮、多位扫描到动态刷新与消隐原理
笔记·单片机·嵌入式硬件·51单片机
roman_日积跬步-终至千里2 小时前
【算法3】二叉树中的最大路径和
算法
小柯博客2 小时前
01 · 点亮 STM32MP25 的硬件视频编解码:VPU 与那些“安静“的坑
c语言·笔记·stm32·单片机·嵌入式硬件·嵌入式·视频编解码
欧叶冲冲冲2 小时前
uv Python 环境管理笔记
笔记·python·uv
自小吃多2 小时前
Capture软件原理图PDF输出笔记
笔记·嵌入式硬件