Skip to content

排序算法分类与复杂度总览

排序:程序员的基本功

排序是算法中最基础的问题,也是面试中出现频率最高的话题之一。

但排序算法种类繁多:冒泡、选择、插入、归并、快速、堆排、计数、桶排、基数……

它们有什么区别?什么时候该用哪个?

今天,让我们系统性地梳理排序算法家族。

排序算法全景图

排序算法
├── 比较排序
│   ├── O(n²) 类
│   │   ├── 冒泡排序
│   │   ├── 选择排序
│   │   └── 插入排序
│   ├── O(n log n) 类
│   │   ├── 归并排序
│   │   ├── 快速排序
│   │   └── 堆排序
│   └── 其他
│       └── 希尔排序
└── 非比较排序
    ├── 计数排序
    ├── 桶排序
    └── 基数排序

复杂度总览

排序算法平均时间最坏时间空间稳定性
冒泡排序O(n²)O(n²)O(1)稳定
选择排序O(n²)O(n²)O(1)不稳定
插入排序O(n²)O(n²)O(1)稳定
希尔排序O(n^1.3)O(n²)O(1)不稳定
归并排序O(n log n)O(n log n)O(n)稳定
快速排序O(n log n)O(n²)O(log n)不稳定
堆排序O(n log n)O(n log n)O(1)不稳定
计数排序O(n + k)O(n + k)O(k)稳定
桶排序O(n + k)O(n²)O(n + k)稳定
基数排序O(nk)O(nk)O(n + k)稳定

什么是「稳定」的排序?

稳定性指的是排序后相同元素的相对顺序是否保持不变。

不稳定排序示例:
原始: [2₁, 1, 2₂]
排序后: [1, 2₂, 2₁]  ← 2 的相对顺序变了!

稳定排序示例:
原始: [2₁, 1, 2₂]
排序后: [1, 2₁, 2₂]  ← 2 的相对顺序保持

什么时候需要稳定性?

当排序的元素不只是数字,而是有多个属性时。

例如按成绩排序后,再按姓名排序——如果排序不稳定,姓名排序会打乱成绩排序的结果。

如何选择排序算法?

按数据量选择

数据量推荐算法原因
n ≤ 50插入排序小数据量时常数小
n ≤ 10000快速排序综合性能最优
n 非常大外部排序内存装不下

按数据特点选择

数据特点推荐算法原因
基本有序插入排序有序时接近 O(n)
完全随机快速排序综合性能最优
有范围限制计数/桶/基数可达线性时间
需要稳定归并排序稳定的 O(n log n)
需要最坏情况堆排序/归并排序最坏也是 O(n log n)

按空间限制选择

空间限制推荐算法
O(1)堆排序、希尔排序、选择排序
O(log n)快速排序(递归栈)
O(n)归并排序、计数排序、桶排序、基数排序

排序算法的「三足鼎立」

在面试中最常被问到的三种排序算法是:快速排序、归并排序、堆排序

为什么是这三个?

  1. 都是 O(n log n):渐近时间复杂度最优
  2. 各有特点:快速排序实际最快,归并排序稳定,堆排序最稳定(最坏情况)
  3. 延伸问题多:partition、三路划分、Top K、手写堆……

各算法的特点

冒泡排序

  • 最简单,但效率最低
  • 适合教学,不适合实际使用
  • 优化:提前终止 + 记录最后交换位置

选择排序

  • 交换次数最少(最多 n 次)
  • 但无论数据如何都是 O(n²)
  • 不稳定

插入排序

  • 小数据量和基本有序时效率高
  • 实际排序中,经常在快速排序的递归到小数据量时切换到插入排序
  • 稳定

希尔排序

  • 插入排序的改进版
  • 通过「跳跃式」插入减少比较次数
  • 不稳定

归并排序

  • 稳定 + 最坏 O(n log n)
  • 但需要额外 O(n) 空间
  • 适合外部排序(磁盘文件分段读入)

快速排序

  • 实际应用中最快
  • 但最坏情况 O(n²) 需要优化(随机 pivot、三数取中等)
  • 不稳定

堆排序

  • 不需要递归,用数组直接实现
  • 最坏情况也是 O(n log n)
  • 不稳定

计数排序

  • 适用于范围小的整数排序
  • 时间 O(n),但空间取决于数据范围
  • 稳定

桶排序

  • 适用于数据均匀分布
  • 平均 O(n),最坏 O(n²)
  • 稳定

基数排序

  • 适用于整数或字符串排序
  • 按位稳定排序,k 为位数
  • 稳定

总结

排序算法的选择取决于多种因素:

  1. 数据规模:小数据用插入排序,大数据用快速/归并/堆排序
  2. 数据特点:基本有序用插入排序,有范围用计数/桶/基数
  3. 稳定性要求:需要稳定用归并排序
  4. 空间限制:空间紧张用堆排序/插入排序
  5. 最坏情况:需要保证最坏性能用堆排序/归并排序

没有最好的排序算法,只有最适合场景的排序算法。

面试追问方向

  • 什么是排序的稳定性?举例说明稳定和不稳定的排序
  • 快速排序的最坏情况是什么?如何优化?
  • 为什么说归并排序适合外部排序(磁盘排序)?
  • 堆排序的空间复杂度是多少?它是原地排序吗?
  • 计数排序、桶排序、基数排序的适用场景是什么?

基于 VitePress 构建