• 请不要在回答技术问题时复制粘贴 AI 生成的内容
tqbgolegai201343
V2EX  ›  程序员

面试背了八大排序,工作几年后发现大部分用不上

  •  
  •   tqbgolegai201343 · 3h 40m ago · 641 views

    面试的时候八大排序倒背如流,工作几年后发现实际开发里真用得上的就那么两三个。整理一下哪些该深挖、哪些面试背完就得了。

    先放结论:实际开发 90% 的场景,直接用语言自带的排序就够了。 Java 的 Arrays.sort()、Python 的 sorted(),底层都是经过高度优化的( Tim Sort / 双轴快排),比你手写的任何排序都快。手写排序的意义在于理解原理和应对面试,不是让你在生产环境替代标准库。

    逐个说:

    快速排序 — 唯一值得深挖的

    实际工程里接触最多的排序底层就是快排。Java Arrays.sort() 对基本类型用双轴快排( Dual-Pivot Quicksort ),理解快排的分区逻辑对你看懂标准库源码有帮助。

    关键点不是怎么写,是怎么选 pivot。取第一个元素是教科书写法,实际遇到已排序数组直接退化到 O(n²)。三数中值法(左端、右端、中位数的中间值)是基本操作,更稳的是随机选 pivot 。

    // 核心:分区,不是排序本身
    int partition(int[] a, int low, int high) {
        int pivot = a[low]; // 实际用三数中值法
        while (low < high) {
            while (low < high && a[high] >= pivot) high--;
            a[low] = a[high];
            while (low < high && a[low] <= pivot) low++;
            a[high] = a[low];
        }
        a[low] = pivot;
        return low;
    }
    

    平均 O(nlogn),最坏 O(n²),不稳定。但实际优化后(随机 pivot + 小数组切插入排序)极难触发最坏情况。

    归并排序 — 理解 Tim Sort 的基础

    Tim Sort ( Python/Java 对象排序用的)就是归并的变种。归并排序本身在面试里考得多,实际手写场景少。

    几个容易被问的细节:

    • 时间复杂度最好最坏都是 O(nlogn),稳定
    • 额外空间是 O(n),不是 O(1)——需要临时数组,这点很多人记错
    • 适合链表排序(不需要随机访问)、外部排序(数据量大到内存放不下)

    堆排序 — 知道原理就行

    面试会问 Top-K 问题,本质就是堆。但手写堆排序的场景我工作几年没遇到过。理解大根堆/小根堆的调整逻辑,知道 PriorityQueue 怎么用,够了。

    时间复杂度 O(nlogn),不稳定。堆排序的常数比快排大,实际跑起来比快排慢,所以标准库基本不用纯堆排序。

    插入排序 — 小数据量王者

    这个反而容易被忽略。当数据量小(通常 < 47 )时,插入排序比快排快——没有递归开销,常数小。Java 的 Arrays.sort() 在子数组小于阈值时就会切到插入排序(双轴快排里叫 "insertion sort on small arrays")。

    大部分已排序时效率高,最好情况 O(n)。稳定,额外空间 O(1)。

    冒泡排序 — 面试背完就得了

    唯一的价值是理解"交换排序"的思路。实际开发没有任何场景该用冒泡。加 flag 优化的版本最好情况 O(n),但插入排序同样能做到且常数更小。

    别拿冒泡去面试写手撕代码,写快排或归并。

    选择排序 — 同上

    不稳定,且最好最坏都是 O(n²)。没有任何实际优势,唯一的教学价值是理解"选择"思路。

    希尔排序 — 知道是插入排序的改进就行

    希尔排序是插入排序的分组改进版,通过增量序列逐步缩减让元素大致有序。时间复杂度取决于增量序列,最好可以到 O(nlogn),最坏 O(n²)。

    实际工程基本不用,但面试偶尔会问"希尔排序和插入排序的关系"。

    桶排序 / 计数排序 — 特定场景才用

    非比较排序,时间复杂度可以到 O(n),但限制大:

    • 值域必须是可枚举的整数范围
    • 值域 k 和数据量 n 接近时才划算( k >> n 时空间浪费严重)
    • **额外空间 O(k)**,不是 O(1)

    实际场景:给百万级年龄数据排序( 0-150 的值域),计数排序秒杀一切比较排序。但你给字符串排序就别想了。

    一张表总结(修正了常见错误):

    排序 平均时间 最坏 稳定 额外空间 实际价值
    快排 O(nlogn) O(n²) 不稳定 O(logn) ★★★ 最高
    归并 O(nlogn) O(nlogn) 稳定 O(n) ★★★ Tim Sort 基础
    堆排 O(nlogn) O(nlogn) 不稳定 O(1) ★★ Top-K 场景
    插入 O(n²) O(n²) 稳定 O(1) ★★★ 小数据量王者
    希尔 O(nlogn) O(n²) 不稳定 O(1) ★ 知道原理就行
    冒泡 O(n²) O(n²) 稳定 O(1) ✗ 教学用
    选择 O(n²) O(n²) 不稳定 O(1) ✗ 教学用
    桶/计数 O(n+k) O(n+k) 稳定 O(k) ★★ 特定场景

    网上很多教程的总结表把归并的额外空间写成 O(1)、桶排序写成 O(1),都是错的。归并需要临时数组 O(n),桶/计数排序需要计数数组 O(k)。

    所以面试该重点准备哪些?

    快排(必手撕)、归并(必手撕)、堆排(理解 + Top-K )、插入排序(能说出小数据量优势)。其余的知道原理和复杂度就行,别花时间手写。


    原文有完整的 Java 代码实现(八种排序全有),在我博客上 tanqingbo.cn/Eight-sorting-algorithms ,需要的自查。

    5 replies    2026-08-03 16:53:24 +08:00
    QS0x01
        1
    QS0x01  
       1h 42m ago
    排序都是多少年前的东西了,手撕现在都是并查集这种了
    yxc246800
        2
    yxc246800  
       1h 11m ago
    面试官:叽里咕噜的说什么呢,ai 用的怎么样
    yukunZhan9
        3
    yukunZhan9  
       1h 3m ago

    推广就发推广呗
    v2AKS
        4
    v2AKS  
       46 mins ago
    @Livid ai 文章
    wysnxzm
        5
    wysnxzm  
       44 mins ago
    记个双轴快排就行了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5358 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 09:37 · PVG 17:37 · LAX 02:37 · JFK 05:37
    ♥ Do have faith in what you're doing.