一个四年经验的 Node.js 工程师,把冒泡排序从原理到代码完整拆了一遍。结论先放这儿:它适合学,不适合上生产。
![]()
冒泡排序是最基础的排序算法之一。它的做法是反复遍历列表,比较相邻的两个元素,顺序不对就交换。名字的来源也在这——每一轮走完,较小或较大的元素会像水里的气泡一样浮到列表末端。
具体怎么走?从数组开头开始,比较索引 0 和索引 1 的两个元素。如果前一个比后一个大,交换;否则保持原样。接着比较索引 1 和索引 2,重复同样的判断。一路比到数组末尾,第一轮结束时,最大的元素已经挪到了最后一位。然后对剩下的未排序部分重复整个过程,每一轮都会把下一个最大的元素放到它最终该在的位置上。
复杂度是它被嫌弃的原因。平均情况和最坏情况(数组完全逆序)下,时间复杂度都是平方级;最好情况下能达到线性。由于是原地排序,空间复杂度是常数级。
实现层面,这位工程师给了一版现代 JavaScript 写法,只处理数字排序,但算法本身也能用于字符串按字母排序这类场景。代码里加了 Array.isArray() 校验,防止有人误传非数组参数导致崩溃。另外他先克隆了一份数组,保证不修改原数组。循环里用了一个 swapped 标记,某一轮没有发生任何交换就直接跳出——这是针对已排序数组的优化。
拿 [5, 1, 4, 2] 走一遍:
- 第一轮:5 和 1 比,交换,得 [1, 5, 4, 2];5 和 4 比,交换,得 [1, 4, 5, 2];5 和 2 比,交换,得 [1, 4, 2, 5]。最大的 5 落位。
- 第二轮:1 和 4 比,不换;4 和 2 比,交换,得 [1, 2, 4, 5]。
- 第三轮:1 和 2 比,不换。数组已有序,结束。
最终结果 [1, 2, 4, 5]。
优点有三条:简单,容易理解、解释和书写;不需要额外内存,完全原地排序;配合优化后,遇到已排序列表能立刻停下。
缺点同样明确。效率差,平方级的时间复杂度让它在处理大数据集时远不如归并排序或快速排序。另外它交换过于频繁,不断写内存,无论从机器层面还是计算层面都是有代价的。
所以它的定位很清楚:拿来练算法思维可以,放进生产代码要三思。作者在文末还留了个问题——你知道 JavaScript 里用 Number.isFinite() 优雅地挡掉 NaN、Infinity 和 -Infinity 破坏数字比较的技巧吗?下一篇他会从排序转向查找,讲二分搜索。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.