首页/数据结构/07-sorting/排序算法的稳定性分析 🔗 在 Obsidian 中打开
数据结构 · 07-sorting

排序算法的稳定性分析

重要度 ★★ 数据结构/排序排序稳定性
速查
若序列中存在多个关键字相同的元素,排序后其相对次序保持不变则称算法稳定。口诀:「插冒归基」稳定,「快选希堆」不稳定。稳定性在多关键字排序中至关重要。

稳定性的定义与意义

如果在待排序序列中存在多个关键字相同的元素,经过排序后这些元素的相对次序保持不变,则称该排序算法是稳定的;否则是不稳定的

例:排序前 3a, 1, 3b, 2(3a、3b 关键字相同)。

  • 稳定结果:1, 2, 3a, 3b(3a 仍在 3b 前)
  • 不稳定结果:1, 2, 3b, 3a(相对顺序改变)
为何关心稳定性多关键字排序:先按次要关键字排,再按主要关键字稳定排序。如先按学号排,再按成绩稳定排序,同分者保持学号顺序。

各排序算法稳定性总表

排序算法稳定性平均时间空间
直接插入排序✅ 稳定$O(n^2)$$O(1)$
折半插入排序✅ 稳定$O(n^2)$$O(1)$
希尔排序❌ 不稳定$O(n^{1.3})$$O(1)$
冒泡排序✅ 稳定$O(n^2)$$O(1)$
快速排序❌ 不稳定$O(n\log n)$$O(\log n)$
简单选择排序❌ 不稳定$O(n^2)$$O(1)$
堆排序❌ 不稳定$O(n\log n)$$O(1)$
归并排序✅ 稳定$O(n\log n)$$O(n)$
基数排序✅ 稳定$O(d(n+r))$$O(n+r)$
计数排序✅ 稳定$O(n+k)$$O(k)$
桶排序✅ 稳定$O(n)$$O(n)$
口诀「插冒归基」稳定,「快选希堆」不稳定

为什么不稳定?逐一分析

  • 希尔排序 ❌:分组插入,不同组间交换打乱相同关键字顺序。反例 [3a,1,3b,2]
  • 快速排序 ❌:分区时相同关键字可能被分到两侧。反例 [3a,3b,1,2] 选 3a 为基准。
  • 简单选择排序 ❌:交换操作打乱顺序。反例 [3a,1,3b,2] 第 2 趟交换后 3a、3b 反了。
  • 堆排序 ❌:建堆与调整时父/子交换打乱顺序。反例 [4a,4b,3]

为什么稳定?逐一分析

  • 直接插入排序 ✅:仅当当前元素 < 前面元素才移动,相等不交换。
  • 冒泡排序 ✅:仅相邻元素逆序才交换,相等不交换。
  • 归并排序 ✅:合并时相同关键字优先取前半部分元素。
  • 基数排序 ✅:按位分配收集,低位相同者保持原顺序。

手算示例

[5a, 3, 5b, 1, 2] 用直接插入排序:

[5a, 3, 5b, 1, 2]
[3, 5a, 5b, 1, 2]   插入 3
[3, 5a, 5b, 1, 2]   插入 5b(=5a,不移动,插在 5a 后)✓稳定
[1, 3, 5a, 5b, 2]   插入 1
[1, 2, 3, 5a, 5b]   插入 2

结果 5a 仍在 5b 前,稳定 ✓。快速排序选第一个为基准时,5a、5b 可能反序,不稳定 ✗。

多关键字排序学生记录 (学号, 成绩) 先按学号排,再按成绩稳定排序,同分者保持学号顺序 (101 在 103 前,102 在 104 前)。

易错点

注意
  1. 快速排序不稳定(常被误以为稳定)
  2. 选择排序不稳定(交换打乱相等元素顺序)
  3. 堆排序不稳定(建堆/调整打乱顺序)
  4. 稳定性取决于实现;理论不稳定的可改成稳定,但增加时空开销
  5. 「插冒归基」是稳定的必须记住

核心结论

必背口诀「插冒归基稳定,快选希堆不稳定」。稳定的原因:相等元素不交换(插/冒)、合并优先前半(归并)、低位保序(基数)。多关键字排序必须用稳定算法。

记忆卡片

什么是稳定性?
相同关键字元素的相对次序排序后不变,则稳定。
快速排序稳定吗?
不稳定。分区交换可能打乱相同关键字相对顺序。
四种稳定排序?
直接插入、冒泡、归并、基数(插冒归基)。
堆排序为何不稳定?
建堆与调整中父/子交换可能打乱相同关键字顺序。

交互动画 · 稳定 vs 不稳定结果

输入 [3a, 1, 3b, 2]:观察相同的 3a、3b 排序后相对顺序

相关知识点

(暂无关联知识点)