408 数据结构:快排 / 堆排 / 归并 / 希尔 等排序算法对比(复杂度、稳定性、真题考点

408 数据结构:快排 / 堆排 / 归并 / 希尔 等排序算法对比(复杂度、稳定性、真题考点)

排序是 408 数据结构的独立章节,考点密集但分散。选择题常考稳定性、最好最坏复杂度、空间复杂度、比较次数;大题常考某种排序的逐步执行过程(尤其是快排、堆排、归并)。本文按 408 考纲对八种内部排序做横向对比,聚焦真题高频考法。

可以自己去网站上动手体验一下

内容分 6 节:

  1. 八种内部排序总览

  2. 稳定性判断

  3. 最好/最坏情况分析

  4. 空间复杂度

  5. 比较次数与移动次数

  6. 真题常见考法 + 速查表


一、八种内部排序总览

算法 最好时间 平均时间 最坏时间 空间 稳定性
直接插入排序 O(n) O(n²) O(n²) O(1) 稳定
折半插入排序 O(n log n) O(n²) O(n²) O(1) 稳定
希尔排序 --- 约 O(n^1.3) O(n²) O(1) 不稳定
冒泡排序 O(n) O(n²) O(n²) O(1) 稳定
快速排序 O(n log n) O(n log n) O(n²) O(log n) 不稳定
简单选择排序 O(n²) O(n²) O(n²) O(1) 不稳定
堆排序 O(n log n) O(n log n) O(n log n) O(1) 不稳定
归并排序 O(n log n) O(n log n) O(n log n) O(n) 稳定

非比较排序(突破 O(n log n) 下界):

算法 时间 空间 稳定性
基数排序 O(d × (n + r)) O® 稳定

d = 关键字位数,r = 基数(十进制 r = 10),n = 记录数。


二、稳定性判断

口诀 :快选希堆不稳定,其余稳定。

  • 不稳定:快 速排序、简单选 择排序、希 尔排序、堆排序
  • 稳定:直接插入、折半插入、冒泡、归并、基数

稳定性的本质:排序过程中是否可能把两个关键字相同的元素的相对位置颠倒。

为什么快排不稳定

快排的 partition 会把等于基准的元素交换到两侧,可能破坏相同关键字元素的原始顺序。

例:序列 3a, 1, 3b, 2,以 3a 为基准,partition 后可能变成 1, 2, 3b, 3a,3a 和 3b 的相对位置颠倒。

为什么堆排不稳定

建堆和调整堆时,父子交换会跨越多个相同关键字的元素位置。

为什么希尔排序不稳定

不同增量分组时,相同关键字可能分到不同子序列,组内调整可能改变它们的相对位置。

为什么简单选择排序不稳定

每趟从未排序部分选最小值,与未排序部分第一个交换。例 5a, 3, 5b, 2, 1,第一趟选最小 1 与 5a 交换,5a 被抛到后面,超过了 5b。


三、最好 / 最坏情况分析

场景 最快算法 原因
数据基本有序 直接插入排序 O(n) 内层循环几乎不执行
数据基本有序 冒泡排序 O(n) 加"本趟是否交换"标志后第一趟即终止
数据完全逆序 快排退化为 O(n²) 每次 partition 只分出 1 个元素
任意分布要求 O(n log n) 归并排序、堆排序 不受初始分布影响

快排最坏情况

基准选择不当(如总是选最左/最右,而数据已经有序或逆序)会导致每次 partition 只减少 1 个元素,退化为 O(n²)。

工程优化:随机选基准、三数取中等。408 考试一般按"直接取第一个元素为基准"处理。

快排最好情况

每次 partition 恰好均分,递归深度 log n,总比较次数 n log n。

堆排序为什么稳定在 O(n log n)

  • 建堆:O(n)
  • n 次调整:每次 O(log n),合计 O(n log n)
  • 总时间:O(n log n),与初始顺序无关

四、空间复杂度

空间 算法
O(1) 插入、冒泡、选择、希尔、堆排序
O(log n) 快速排序(递归栈平均深度)
O(n) 归并排序
O® 基数排序(r 为基数)

易错点:

  • 快排的空间是 O(log n)(平均)到 O(n)(最坏),取决于 partition 的划分均匀性
  • 归并排序需要 O(n) 的辅助数组,不能原地

五、比较次数与移动次数

算法 比较(最好) 比较(最坏) 移动(最好) 移动(最坏)
直接插入 n−1 n(n−1)/2 0 n(n−1)/2
冒泡排序 n−1 n(n−1)/2 0 3n(n−1)/2
简单选择 n(n−1)/2 n(n−1)/2 0 3(n−1)

三个 408 高频结论

  1. 简单选择排序的比较次数固定为 n(n−1)/2,与初始序列无关
  2. 冒泡排序每次交换需要 3 次赋值 (temp = a; a = b; b = temp),而插入排序每次移动只需 1 次赋值。因此同为 O(n²),插入比冒泡快 3-5 倍
  3. 直接插入排序的最少移动次数为 0(输入有序时),最多为 n(n−1)/2

六、真题常见考法 + 速查表

考法 1:稳定性辨析(选择题)

典型题干:"下列排序算法中不稳定的是?"

答题:套"快选希堆"口诀。

考法 2:最佳算法选择(选择题)

典型题干:"对关键字基本有序的序列,以下排序方法中效率最高的是?"

答:直接插入排序(最好 O(n))。

变体:

  • "数据规模小且要求原地排序" → 插入或希尔
  • "任意数据要求稳定 + O(n log n)" → 归并排序
  • "要求 O(1) 空间 + O(n log n) 最坏" → 堆排序
  • "平均性能最优" → 快速排序

考法 3:逐步执行过程(大题)

典型题干:给定序列,写出快排/堆排/归并每一趟(或某一趟后)的状态。

手算要点:

  • 快排:每趟 partition 产生一个基准就位,两侧递归
  • 堆排:先建堆(自底向上),再每次把堆顶与末尾交换后下调
  • 归并:自底向上两两合并,每趟子序列长度翻倍

考法 4:排序趟数与初始序列的关系(选择题)

算法 趟数是否与初始序列相关
直接插入、冒泡 可能相关(最好情况可能提前终止)
简单选择、堆排、归并 无关(趟数固定)
快排 相关(取决于划分均匀性)

考法 5:比较次数下界

基于比较的排序算法时间下界为 Ω(n log n)。证明思路:n! 种输入排列,每次比较最多区分两种情况,需要 log₂(n!) ≈ n log n 次比较。

非比较排序(基数、计数、桶)可以突破这一下界,但需要数据具有特殊结构。


速查表

考点 考频 关键记忆
稳定性口诀 ★★★★★ 快选希堆不稳定
时间复杂度对比 ★★★★★ 快排平均最优;归并堆排最坏最优
空间复杂度 ★★★★★ 快排 log n;归并 n;其余 1
逐步执行手算 ★★★★★ 快排、堆排、归并大题必考
基本有序选插入 ★★★★☆ 插入最好 O(n)
比较次数固定的算法 ★★★★☆ 简单选择固定 n(n-1)/2
趟数与初始序列关系 ★★★☆☆ 选择/堆排/归并固定;插入/冒泡/快排可变

codebrick.tech 有快排、堆排、归并、希尔等所有排序算法的交互可视化:输入任意序列逐步执行,每一趟状态并排对比,比较次数和移动次数自动统计。稳定性差异可以通过相同关键字元素的颜色追踪直观看到。免费,不用注册。

参考文章

https://www.codebrick.tech/ds-blog/posts/sorting/comparison.html

相关推荐
Logic1015 小时前
C语言/数据结构字符串题解:最短循环节——找出能重复构成原串的最短基础子串
c语言·数据结构·字符串·枚举·时间复杂度·算法题·kmp优化
129Lab5 小时前
BMS 核心算法:SOC 估算从安时积分到 LSTM-UKF 串级融合的 30 年演进(附 Python 实现)
python·算法·lstm·python3.11·bms·soc估算
kgkg5 小时前
我通过逆向学到了douyin的美颜算法
算法
anew___6 小时前
《从零手写操作系统 (30):环境变量与进程上下文——export/unset与继承语义》
java·开发语言·网络·jvm·算法
垆边人似月.6 小时前
城市连通性(200分 / 并查集)
数据结构·算法·图论
Gust of wind6 小时前
串与KMP模式匹配:存储结构、基本操作、next数组手算
c语言·数据结构·后端·算法
Navigator_Z6 小时前
LeetCode //C - 1283. Find the Smallest Divisor Given a Threshold
c语言·算法·leetcode
by209997 小时前
list:迭代器与资源管理实现的综合叙述(下)
数据结构·c++·笔记·list
啦啦啦啦啦zzzz7 小时前
一致性哈希
服务器·算法·哈希算法·c++20·分布式存储
我不会起名字3227 小时前
二叉树的遍历与二叉搜索树:把递归、迭代、还原树一次讲透
数据结构·leetcode·二叉树·二叉搜索树