跳到主要内容

排序

排序按比较规则重排元素。本文负责分区、归并、稳定性和排序边界。

1. 面试核心​

先记住这几条,再读正文
  • 稳定性。 稳定排序保留比较结果相等项的原始相对顺序。因此,先按次要字段排序,再按主要字段稳定排序,可以保留两层顺序。卡 · 稳定性与多字段排序
  • 比较排序下界。 比较排序最坏比较次数下界为 Ω(n log n)。
  • 快速排序复杂度。 随机化快排期望 O(n log n),最坏仍为 O(n²)。卡 · 分区与合并
  • 重复键处理。 三路快排把键分成小于、等于和大于枢轴三组,递归只处理两侧。大量重复键由此不再反复参与分区。卡 · 重复值与三路分区

2. 分区与合并​

快速排序选取枢轴,分区后递归处理两侧。两侧均衡时有 O(log n) 层。若每次只排除一项,总比较量为 n+(n-1)+…,达到 O(n²)。随机化减少持续坏划分的概率。

归并排序递归排好两半,再按较小者依次合并。每层处理 O(n) 项,共 O(log n) 层。标准数组实现时间 O(n log n),辅助数组空间 O(n)。调用栈另占 O(log n)。

3. 性质比较​

方法最坏时间典型辅助空间常见实现稳定性
插入排序O(n²)O(1)稳定
快速排序O(n²)栈最坏 O(n)不稳定
归并排序O(n log n)O(n)稳定
堆排序O(n log n)O(1)不稳定

插入排序只移动严格更大的项,可保留相等项顺序。归并遇到相等项时优先取左侧,也能保持稳定。比较次数下界来自 n! 种排列的决策树高度。计数排序利用值域 U,可做到 O(n+U),另需值域空间。

3.1 稳定性与多字段排序​

若员工先按入职时间排序,再按部门稳定排序,同部门仍按入职时间排列。稳定性相对比较器的相等关系定义。Java 21 的 Arrays 对象数组排序保证稳定。

3.2 重复值与三路分区​

将区间分成小于、等于、大于枢轴的三段。相等段已就位,只递归处理两侧。全部值相等时,一轮线性分区即可结束。

递归处理较短一侧,再循环处理较长一侧,可将栈深度限制为 O(log n)。这项优化控制栈空间,最坏比较次数仍可为 O(n²)。

4. 使用边界​

小数组或接近有序的数组可考虑插入排序。选择算法还需确认是否允许修改输入。

只取部分极值时,可使用堆。

比较器使用 Integer.compare,避免减法溢出。它还需满足反对称符号关系与传递性。测试排序应同时检查非递减顺序和元素多重集。

5 · 面试题卡片​

本页题目与参考回答

5.1 快速排序为何会退化到 O(n²)?​

考察重点:分区平衡性与最坏上界。

相关内容:分区与合并。

参考回答

每次只排除一个元素时,比较总量为 O(n²)。

其余元素反复参与分区,规模只减少一项。随机枢轴改善期望成本,最坏上界仍为 O(n²)。

5.2 稳定排序如何支持多字段排序?​

考察重点:比较相等与原始顺序。

相关内容:稳定性与多字段排序。

参考回答

先按次要字段排序,再按主要字段稳定排序即可。

主要字段相同的项会保留次要字段的顺序。归并时相等优先取左项,就是稳定性的具体实现。

5.3 大量相等键时,三路快排有什么作用?​

考察重点:相等区间与递归范围。

相关内容:重复值与三路分区。

参考回答

三路分区把相等键集中,后续只处理两侧。

全相等输入只需一次 O(n) 扫描。比较器需正确表达相等关系,分区后两侧也要严格缩小。

6. 参考资料​