排序:冒泡和快排的赛跑
两种排序同场竞技的可视化动画:看冒泡怎么一步步挪、快排怎么分区跳跃;数据量一大差距有多悬殊
本页解决的问题
先给结论「排序:冒泡和快排的赛跑」要解决的关键问题是什么?
两种排序同场竞技的可视化动画:看冒泡怎么一步步挪、快排怎么分区跳跃;数据量一大差距有多悬殊
让这个结论先证明自己值得留下。 把这一页当成决策工具,而不是需要背下来的定义。把概念连到一个真实任务、一个可观察结果,以及一个能改变你判断的失败上。
写下一个问题:试完这个方法后,你能用什么证据回答它?
结论听起来很完整,却没有检查最关键的假设。
规则:两条泳道、同一组随机柱子、同样的动画节奏(每一步耗时相同),公平竞赛。留意三件事:①黄色 = 正在比较的柱子 ②紫色 = 快排选中的「基准」③绿色 = 已就位。先用 10 根感受节奏,再点 60 根看差距。
🫧 冒泡排序
相邻两根比较,大的慢慢往右冒 · O(n²) 0次比较⚡️ 快速排序
选个基准劈两半,各自再劈 · 平均 O(n log n) 0次比较🫧 冒泡:蛮力逐个换 O(n²)
每一轮从头到尾扫一遍,相邻两个只要前面比后面大就交换——一轮下来,最大的那个必然「冒」到最右边。简单、直观、绝对不会写错,但 n 个数要扫 n 轮,总账就是 n²。上上课那条红色曲线,就是它的命。
⚡️ 快排:分而治之 O(n log n)
随手指定一根「基准」,比它矮的甩左边、比它高的甩右边——一趟下来基准就位,剩下两堆各自重复这个动作。「劈两半」是不是很眼熟?就是二分的亲戚。这个套路叫分治,下下课讲递归时它还会登场。
🪪 说句实话:没人手写排序
真实工程里,排序就是一行 list.sort(),语言内置的实现比你我手写的都好。那学这个干嘛?为了两种手感:一是看懂「为什么有的代码要跑一晚上」——多半是有人在百万级数据上用了 O(n²) 的套路;二是亲身体会 O(n²) 和 O(n log n) 到底差多少——上面那场赛跑,就是上上课两条曲线的真人版。尺子有了、手感有了,验收 AI 写的代码就有底气了。
「同场赛跑 · 冒泡 vs 快排」里的算法代价曲线
「规则:两条泳道、同一组随机柱子、同样的动画节奏(每一步耗时相同),公平竞赛。」真正训练的不是背诵步骤,而是识别重复工作:输入变大时,程序到底多做了多少次比较、移动或递归。
先找重复工作,再谈快慢
「每一轮从头到尾扫一遍,相邻两个只要前面比后面大就交换—— 一轮下来,最大的那个必然「冒」到最右边 。简单、直观、绝对不会写错,但 n 个数要扫 n 轮,总账就是 n²。上上课那条红色曲线,就是它的命」可以拆成输入规模、每轮做什么、以及是否能缩小下一轮范围三个问题。Big-O 是描述增长趋势的语言,不是对每台机器的精确计时;常数、内存和真实数据分布也会影响最终结果。
- 排序思想两大流派 :蛮力逐个换(冒泡)vs 分而治之(快排)
- 「劈两半」再次立功 :快排是二分思想的亲戚,分治套路后面讲递归还会见
- 数据量大时算法选择是生死线 :60 根柱子已经肉眼可见,百万条就是「跑一晚上」和「一秒出结果」
别把理论最优当成无条件最优
面对 AI 写出的算法,先用小输入手算一遍,再用逐渐放大的数据做基准测试。这样才能把「真实工程里,排序就是一行 list.sort() ,语言内置的实现比你我手写的都好。那学这个干嘛?」从一句结论变成可检查的性能判断。
从「同场赛跑 · 冒泡 vs 快排」走到「两种思想 · 各是什么套路」
「同场赛跑 · 冒泡 vs 快排」先把问题落在「规则:两条泳道、同一组随机柱子、同样的动画节奏(每一步耗时相同),公平竞赛。 留意三件事:①黄色 = 正在比较的柱子 ②紫色 = 快排选中的「基准」③绿色 = 已就位 。先用 10 根感受节奏,再点 60 根看差距」上;到了「两种思想 · 各是什么套路」,讨论继续推进到「每一轮从头到尾扫一遍,相邻两个只要前面比后面大就交换—— 一轮下来,最大的那个必然「冒」到最右边 。简单、直观、绝对不会写错,但 n 个数要扫 n 轮,总账就是 n²。上上课那条红色曲线,就是它的命」。两段连起来,重点就不只是记住一个结论,而是看清它成立所依赖的条件。
把这条判断带到下一个场景
算法题换成真实任务后,先找出重复工作,再问输入规模如何变化,最后用一个小基准验证理论判断。这样不会把复杂度记成脱离场景的标签。
- 「同场赛跑 · 冒泡 vs 快排」:规则:两条泳道、同一组随机柱子、同样的动画节奏(每一步耗时相同),公平竞赛。 留意三件事:①黄色 = 正在比较的柱子 ②紫色 = 快排选中的「基准」③绿色 = 已就位 。先用 10 根感受节奏,再点 60 根看差距
- 「两种思想 · 各是什么套路」:每一轮从头到尾扫一遍,相邻两个只要前面比后面大就交换—— 一轮下来,最大的那个必然「冒」到最右边 。简单、直观、绝对不会写错,但 n 个数要扫 n 轮,总账就是 n²。上上课那条红色曲线,就是它的命
- 「最后的要点」:不用手写,但要看得懂 :一行 .sort() 背后的快慢账,是验收代码的基本功
最后的「最后的要点」把讨论落到「不用手写,但要看得懂 :一行 .sort() 背后的快慢账,是验收代码的基本功」。回看这条线索时,最值得保留的是:当输入、规模或风险改变,哪些判断需要重新做一遍。
✅ 这一课想和你分享的
- 排序思想两大流派:蛮力逐个换(冒泡)vs 分而治之(快排)
- 「劈两半」再次立功:快排是二分思想的亲戚,分治套路后面讲递归还会见
- 数据量大时算法选择是生死线:60 根柱子已经肉眼可见,百万条就是「跑一晚上」和「一秒出结果」
- 不用手写,但要看得懂:一行 .sort() 背后的快慢账,是验收代码的基本功
我把这篇文章里的一个判断改写成了今天可以验证的小实验。比记住结论更有用的是,知道下一步要观察什么。
读完以后我先回头找它成立的条件,而不是直接把方法搬进项目。这个顺序让后面的取舍清楚很多。
如果把这个判断放到真实工作里,最先需要补的约束是什么?我想知道从阅读到第一次实践之间,哪一步最值得先做。
还没有这篇文章的讨论。