快速排序
面试官说:"手写一个快速排序。"
候选人小张刷刷刷写完了:
面试官看了半天,问:"你这个代码在某些情况下会出问题,你知道吗?"
小张愣住了...
一、从一个问题开始
快速排序是面试中出现频率最高的排序算法,90%的候选人能写出基本版本,但能正确处理边界情况的不超过60%,能讲清楚优化策略的不到30%。
今天,我们把快速排序彻底讲透。
【直观类比】
快速排序就像分班考试:
- 找一个"中位数"同学作为基准
- 让比他矮的站左边,比他高的站右边
- 然后左边、右边各自重复这个过程
最终,所有同学都站到了正确的位置。
二、核心原理:分治思想
2.1 快速排序的核心
快速排序的核心是分治:把大问题分解成小问题,分别解决。
2.2 partition过程详解
partition的目标是把数组分成两部分:左边的都 <= pivot,右边的都 > pivot。
方法一:双边循环法(常用)
方法二:单边循环法(更简洁)
2.3 分区过程图解
三、递归过程演示
四、面试高频追问
4.1 追问一:快速排序为什么快?
4.2 追问二:快速排序的缺点是什么?
- 最坏情况:基准选择不当(如有序数组选第一个或最后一个),退化成O(n²)
- 不稳定:相等的元素可能改变相对顺序
- 递归深度:最坏情况下递归深度是O(n),可能导致栈溢出
4.3 追问三:如何避免最坏情况?
三数取中法:
五、优化策略
5.1 小数据量切换到插入排序
5.2 尾递归优化
5.3 三路划分(处理重复元素)
六、边界与特例
6.1 空数组和单元素数组
6.2 重复元素
重复元素多时,partition会极度不平衡。三数取中和三路划分能有效缓解。
6.3 基准选择不当
七、常见误区
❌ 误区一:快速排序是最快的排序
实际情况:在随机数据下,快速排序确实快;但在极端情况下可能退化成O(n²)。数据量小时可能不如插入排序。
❌ 误区二:partition只能用双边循环
实际情况:单边循环更简洁,更不容易出错(如处理边界条件)。
❌ 误区三:快速排序是稳定的
实际情况:快速排序是不稳定的。如果需要稳定排序,可以用归并排序。
八、记忆技巧
用口诀记住partition过程:
双边循环:右往左找小,左往右找大,相遇放基准
用对比记住快排和归并:
快排先排后递归,归并先递后合并;快排原地不合并,归并需要额外位
九、实战检验
检验一:力扣912题 - 排序数组
检验二:Top K 问题
十、总结
快速排序的核心是分治和原地分区:
- 分治:大问题分解成小问题
- 原地分区:不需要额外数组
- 基准选择:决定性能的关键
记住这三句话:
- 快速排序的快,来自原地分区和良好的缓存局部性
- 基准选择不当会让快排变成慢排
- 处理重复元素时,三路划分是利器
下一篇文章,我们来聊聊快速排序的孪生兄弟——归并排序。