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

考点频率:★★★★☆(选择题常考,归并排序的复杂度与稳定性是重点,基数排序常考其适用场景)
难度:⭐⭐⭐⭐(归并排序需理解分治与合并,基数排序需理解分配与收集过程)
建议:重点掌握归并排序的“分治+合并”思想及时间复杂度;重点掌握基数排序的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=0d−1d-1d1
    • 分配:根据第 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
720355436457,657329,839

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

第2趟(按十位分配)

桶0桶1桶2桶3桶4桶5桶6桶7桶8桶9
329436457,657
720839

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

第3趟(按百位分配)

桶0桶1桶2桶3桶4桶5桶6桶7桶8桶9
329,355436,457657720

收集后:[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]

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值