快速排序动画演示

挑一个基准把区间分成两半,左右各自再分。

键盘:← → 单步 ·空格 播放/暂停 · R 重置 ·Home/End 到两端

快速排序靠一个基准把区间劈成两半:左边都比它小,右边都不比它小,基准落定的那个下标从此就是它的最终位置,之后再也不参与。这一页用对撞指针画:i 从左往右找不该在左边的,j 从右往左找不该在右边的,两个都停下就互换一次;i 越过 j 时,j 恰好停在最后一个比基准小的位置,把基准换过去,分区结束。

基准可以选首元素、尾元素、三数取中或随机。「首元素 + 正序数据」是经典的最坏情况,区间每次只剥掉一个元素,递归退化成 O(n²);换成三数取中或随机就能避开。随机那一档走的是派生种子的确定性伪随机,同一个参数每次跑出的步骤完全一致,进度条拖回去还能对上。

快速排序演示怎么用

  • 认指针:标注 i、j 是对撞的两个指针,红色那格是基准;绿格表示它已经落在最终位置上。
  • 换基准:基准策略下四档:首元素、尾元素、三数取中、随机。同一份数据换档能直接看到分区形状和步数差多少。
  • 数分区:计数条三项:比较、交换、分区。每次分区定死一个元素,所以分区次数不会超过 n。
  • 看退化:把形态切到「正序」、基准留在「首元素」,看区间一边倒地缩小;再换成三数取中对一遍,这就是它最坏与平均的差别。

常见问题

为什么基准要先换到区间头部?

换到 lo 就腾出了 a[lo] 这一格,扫描期间它不当成待处理元素,两个指针只在 [lo+1, hi] 里活动。最后 j 停在最后一个比基准小的位置上,把 a[lo] 跟它一换,基准自然落定,不用另外记录空位。

两个内层循环的等号为什么一边严一边松?

i 用 a[i] < pv,j 用 a[j] >= pv,等于基准的元素统一交给 j 那侧往左推。两边都用严格或都松弛,全等数据上就会有一侧不动、指针永远撞不到一起,陷入死循环。

快排不稳定,工程上还在用它,为什么?

它的比较虽然比归并多一点,但每次交换都在同一段连续内存里发生,缓存命中率远高于归并那种要顺带扫辅助数组的写法;加上原地、常数小,平均时间又是最优的。要稳定就换归并或加次级键。

演示编号 A06无需安装,手机端同样可用按 Ctrl + K 搜工具与演示

顺手能用上的工具