408 数据结构:快排 / 堆排 / 归并 / 希尔 等排序算法对比(复杂度、稳定性、真题考点)
-
- 一、八种内部排序总览
- 二、稳定性判断
- [三、最好 / 最坏情况分析](#三、最好 / 最坏情况分析)
- 四、空间复杂度
- 五、比较次数与移动次数
-
- [三个 408 高频结论](#三个 408 高频结论)
- [六、真题常见考法 + 速查表](#六、真题常见考法 + 速查表)
-
- [考法 1:稳定性辨析(选择题)](#考法 1:稳定性辨析(选择题))
- [考法 2:最佳算法选择(选择题)](#考法 2:最佳算法选择(选择题))
- [考法 3:逐步执行过程(大题)](#考法 3:逐步执行过程(大题))
- [考法 4:排序趟数与初始序列的关系(选择题)](#考法 4:排序趟数与初始序列的关系(选择题))
- [考法 5:比较次数下界](#考法 5:比较次数下界)
- 速查表

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

内容分 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 高频结论
- 简单选择排序的比较次数固定为 n(n−1)/2,与初始序列无关
- 冒泡排序每次交换需要 3 次赋值 (
temp = a; a = b; b = temp),而插入排序每次移动只需 1 次赋值。因此同为 O(n²),插入比冒泡快 3-5 倍 - 直接插入排序的最少移动次数为 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