60 秒回答模板

常见 O(nlogn) 排序有快速排序、归并排序、堆排序,很多语言内置排序还会用 TimSort 或混合排序。快排通过 partition 分治,平均 O(nlogn)、原地、缓存友好,但不稳定且最坏 O(n²),适合内存数组的通用排序。归并排序通过先分再合并,时间稳定 O(nlogn)、稳定,适合链表、外部排序和需要稳定性的场景,但数组归并通常要 O(n) 额外空间。堆排序用堆反复取最大或最小,原地且最坏 O(nlogn),但不稳定、常数和缓存局部性一般,更常用于 TopK 或需要最坏复杂度兜底的场景。选择时要看数据规模、是否稳定、内存限制、输入分布和是否在磁盘上。

考点 核心机制与工程取舍
难度 中高频面试题
回答目标 按定义、机制、场景讲清楚

深入解析

01

先说明比较排序下界

基于比较的通用排序,平均意义上很难突破 O(nlogn),因为排序结果对应大量排列,比较决策树高度需要 log(n!) 量级。非比较排序如计数、桶、基数排序依赖值域条件,不属于同一类通用比较排序。

02

快排重在 partition

快排选 pivot,把数组分成小于和大于 pivot 的两部分再递归。它平均性能好、常数小、原地、缓存友好,但 pivot 极端时会退化到 O(n²),通常用随机 pivot、三数取中和三路分区缓解。

03

归并重在稳定合并

归并排序递归拆分后按顺序合并两个有序段。它每层合并 O(n),层数 O(logn),最坏也是 O(nlogn),天然稳定,适合链表排序和外部排序,因为可以顺序读写。

04

堆排重在最坏兜底

堆排序先建堆,再反复把堆顶元素交换到尾部并下沉调整。它额外空间 O(1),最坏 O(nlogn),但跳跃访问多,缓存局部性不如快排,且不稳定。

05

场景选择要有维度

需要稳定性选归并或稳定混合排序;内存紧张且要原地可考虑快排或堆排;数据在磁盘上优先归并;只要最大/最小 K 个元素常用堆;输入局部有序时内置 TimSort 类算法通常表现更好。

易错点

  • 只列快排、归并、堆排名字,不比较时间、空间、稳定性和适用场景。
  • 把快排说成最坏也是 O(nlogn),忽略固定 pivot 在有序输入上的退化。
  • 认为堆排序因为最坏 O(nlogn) 就一定比快排更快,忽略常数和缓存局部性。
  • 把所有 O(nlogn) 排序都说成稳定,忽略快排和堆排通常不稳定。

面试官追问

为什么归并排序稳定?

合并两个有序段时,相等元素优先取前一个有序段里的原有元素,就能保留相等元素的相对顺序。

快排为什么实际常用?

平均性能好,原地排序,常数小,缓存局部性较好。只要通过随机 pivot、三数取中和小数组插入排序等优化,实际表现通常很强。

堆排序为什么不是默认最快?

堆操作需要频繁父子跳转访问,缓存局部性差;相同 O(nlogn) 下常数可能高于优化快排或混合排序。

外部排序为什么常用归并?

外部排序数据放在磁盘,顺序读写比随机访问更友好。归并可以先生成有序段,再多路归并,天然适合磁盘和流式处理。