每天学一个算法-快速排序(Quick Sort)

📘 快速排序(Quick Sort)

1. 问题定义

给定数组 (A[1...n]),目标是将其重排为:

A\[1\]≤A\[2\]≤⋯≤A\[n\]\]\[A\[1\] \\le A\[2\] \\le \\dots \\le A\[n\]\]\[A\[1\]≤A\[2\]≤⋯≤A\[n\]

2. 核心思想

快速排序基于:

🔹 分治(Divide and Conquer)

将问题递归拆解为两个子问题。

在本算法中具体体现为:

  1. 选择一个元素作为枢轴(pivot)
  2. 执行划分(partition)
  3. 对左右子数组递归排序

3. 核心术语(精确定义 + 可理解解释)

🔸 3.1 枢轴(Pivot)

定义:

用于划分数组的参考元素

作用:

将数组分为两部分:

\\text{左区间} \\le pivot \\le \\text{右区间}

理解:

pivot 是"分界值",它最终会被放到正确位置

🔸 3.2 划分(Partition)

定义:

对区间 (A[l...r]) 重排,使:

∀i\p, A\[j\]≥A\[p\]\]\[ \\forall i \< p,\\ A\[i\] \\le A\[p\] \\quad \\forall j \> p,\\ A\[j\] \\ge A\[p\] \]\[∀i\p, A\[j\]≥A\[p\]

关键点:

  • 只保证"左右关系正确"
  • 不保证内部有序

👉 这是最容易误解的地方

🔸 3.3 递归(Recursion)

定义:

函数调用自身解决子问题

在快排中的作用:

  • 对左区间继续排序
  • 对右区间继续排序

🔸 3.4 原地排序(In-place)

定义:

不依赖额外线性空间

快排特点:

  • 通过交换完成排序
  • 仅使用常数额外空间(不计递归栈)

🔸 3.5 稳定性(Stability)

定义:

相等元素排序后相对顺序是否保持

结论:

快速排序不稳定

4. 算法结构

4.1 主过程

text 复制代码
QuickSort(A, l, r):
    if l < r:
        p = Partition(A, l, r)
        QuickSort(A, l, p-1)
        QuickSort(A, p+1, r)

4.2 划分函数(Lomuto)

text 复制代码
Partition(A, l, r):
    pivot = A[r]
    i = l - 1
    for j = l to r-1:
        if A[j] ≤ pivot:
            i = i + 1
            swap(A[i], A[j])
    swap(A[i+1], A[r])
    return i + 1

5. 核心机制(教学重点)

5.1 三个逻辑区间

在 partition 过程中,数组被划分为:

区间 含义
(A[l..i]A[l..i]A[l..i]) ≤ pivot
(A[i+1..j−1]A[i+1..j-1]A[i+1..j−1]) > pivot
(A[j..r−1]A[j..r-1]A[j..r−1]) 未处理

5.2 循环不变量(Loop Invariant)

在每轮循环开始时成立:

A\[l..i\]≤pivot,A\[i+1..j−1\]\>pivot\]\[ A\[l..i\] \\le pivot,\\quad A\[i+1..j-1\] \> pivot \]\[A\[l..i\]≤pivot,A\[i+1..j−1\]\>pivot

意义:

  • 保证算法过程始终正确
  • 是证明正确性的关键工具

5.3 Partition 的本质

不是排序,而是:

把一个元素(pivot)放到它最终应该在的位置

6. 正确性(简要证明)

6.1 Partition 正确性

循环结束后:

  • 左侧元素全部 ≤ pivot
  • 右侧元素全部 ≥ pivot
  • pivot 被交换到正确位置

6.2 递归正确性

基于归纳法:

  • 子问题规模更小
  • 子问题正确排序
  • 整体有序

7. 时间复杂度

7.1 递推式

T(n)=T(k)+T(n−k−1)+Θ(n)\]\[ T(n) = T(k) + T(n-k-1) + \\Theta(n) \]\[T(n)=T(k)+T(n−k−1)+Θ(n)

7.2 三种情况

情况 复杂度 原因
最优 (n \log n) 划分均匀
最坏 (n^2) 划分极端
平均 (n \log n) 随机分布

🔹 为什么是 (n \log n)

  • 每层处理 (n) 个元素
  • 层数约为 (\log n)

8. 空间复杂度

来源:递归调用栈

情况 空间复杂度
平均 (\log n)
最坏 (n)

9. 枢轴选择对性能的影响

🔸 9.1 固定选择

  • 简单
  • 易退化

🔸 9.2 随机选择

作用:

  • 打乱输入结构
  • 避免极端划分

🔸 9.3 三数取中

降低偏斜划分概率

10. 三路划分(进阶)

动机:

存在大量重复元素时:

  • 普通快排效率下降

解决:

划分为:

\pivot\]\[ \< pivot \\quad = pivot \\quad \> pivot \]\[\pivot

效果:

减少递归规模

11. 与其他排序对比

算法 时间 空间 稳定
快排 平均 (nlog⁡nn \log nnlogn) 原地
归并 (nlog⁡nn \log nnlogn) 额外空间
堆排 (nlog⁡nn \log nnlogn) 原地

12. 常见错误

❌ 错误1:认为 partition 后数组已排序

👉 实际只完成"分区"

❌ 错误2:递归区间写错

错误:

QuickSort(A,l,p)\]\[ QuickSort(A, l, p) \]\[QuickSort(A,l,p)

正确:

QuickSort(A,l,p−1)\]\[QuickSort(A, l, p-1)\]\[QuickSort(A,l,p−1)

❌ 错误3:不理解 i 的含义

i 表示:

复制代码
			$\text{"≤ pivot 区域的右边界"}$

13. 关键结论

  1. 快排核心是 partition
  2. pivot 决定效率
  3. 平均复杂度 (n \log n)
  4. 非稳定排序
  5. 原地算法
相关推荐
炽烈小老头2 小时前
【每天学习一点算法 2026/04/16】逆波兰表达式求值
学习·算法
优家数科2 小时前
水质监测不准?解密云端 TDS 数据建模纠偏算法
算法
木井巳2 小时前
【递归算法】组合总和
java·算法·leetcode·决策树·深度优先·剪枝
coding者在努力2 小时前
被n整除的n位数
c++·算法
黎阳之光2 小时前
去标签化无感定位技术突破,黎阳之光重构空间定位技术路径
大数据·人工智能·算法·安全·数字孪生
见叶之秋2 小时前
【数据结构】详解二叉树和堆
数据结构·算法
CoovallyAIHub3 小时前
MSD-DETR:面向机车弹簧检测的可变形注意力Detection Transformer
算法·架构
CoovallyAIHub3 小时前
不改权重、不用训练!BEM用背景记忆抑制固定摄像头误检,YOLO/RT-DETR全系有效
算法·架构·github
Struggle_97553 小时前
算法知识-从递归入手三维动态规划
算法·动态规划