JavaScript算法 - 冒泡排序
2026年1月7日 18:03
冒泡排序(从小到大)
![]()
/**
* 文字描述,毕竟不如口语表达,所以,这里有一些帮助阅读的方法
* 释义:
* 项:"数组的 0 项",指的是数组 index 为 0 的值
*
* tips:
* 1. 将会用到的数组,都是复杂度最高的数组,也就是原始排序为 [3,2,1] 这样从大到小的数组,有助于直观理解
* 2. 如果觉得有点乱,就关注函数返回的结果。上一步结果,就是我们下一步的根本
*/
如果数组一共有两项
const myArr = [9, 8]
const mySort = (arr) => {
if (arr[0] > arr[1]) {
;[arr[0], arr[1]] = [arr[1], arr[0]]
}
return arr
}
const result = mySort(myArr)
console.log(result, 'result') // [ 8, 9 ]
此时数组变为:[ 8, 9 ] 总结:以上是最简单的排序。数组只有两项,0 项和 1 项。比大小、换位,没了
如果有三个呢
const myArr = [9, 8, 7]
const mySort = (arr) => {
if (arr[0] > arr[1]) {
;[arr[0], arr[1]] = [arr[1], arr[0]]
}
return arr
}
const result = mySort(myArr)
console.log(result, 'result')// [ 8, 9, 7 ]
此时的数组变为:[ 8, 9, 7 ]
看着这个数组,总结:预料之中,0 项和 1 项换位。接下来呢?
排序后数组的含义可以解释为:
可以确定:数组的 1 项,是数组 0 项、1 项中的的最大值
不能确定:数组的 2 项,更大还是更小
!那么,让数组的 1、2 项比大小,就确定了数组中最大的是谁
代码延申
const myArr = [9, 8, 7]
const mySort = (arr) => {
// 第一步
if (arr[0] > arr[1]) {
;[arr[0], arr[1]] = [arr[1], arr[0]]
}
// 走到此处,arr 的值为 [ 8, 9, 7 ]
// 第二步
if (arr[1] > arr[2]) {
;[arr[1], arr[2]] = [arr[2], arr[1]]
}
// 走到此处,arr 的值为 [ 8, 7, 9 ]
return arr
}
const result = mySort(myArr)
console.log(result, 'result') // [ 8, 7, 9 ]
此时的数组变为:[ 8, 7, 9 ]
看着这个数组,总结:延申后,我们确定了最大值,且移动到了最右边
希望这里,你会感受到思路在变清晰
排序后的数组含义可以解释为
可以确定:0 项和 1 项,都比 2 项小。2 项,是数组的最大值
不能确定:数组的 0 项、1 项,谁大
!那么,让数组的 0、1 项比大小。(因为已经确定了 2 项最大,那么,确定了 0、1 的大小关系,就确定了全部的大小关系)
代码再延申
const mySort = (arr) => {
// 第一步
if (arr[0] > arr[1]) {
;[arr[0], arr[1]] = [arr[1], arr[0]]
}
// 走到此处,arr 的值为 [ 8, 9, 7 ]
// 第二步
if (arr[1] > arr[2]) {
;[arr[1], arr[2]] = [arr[2], arr[1]]
}
// 走到此处,arr 的值为 [ 8, 7, 9 ]
// 第三步(与 第一步 完全一致)
if (arr[0] > arr[1]) {
;[arr[0], arr[1]] = [arr[1], arr[0]]
}
// 走到此处,arr 的值为[ 7, 8, 9 ]
return arr
}
const result = mySort(myArr)
console.log(result, 'result') // [ 7, 8, 9 ]
此时的数组变为:[ 7, 8, 9 ],是我们要的结果
思路总结:
我们排序的方式为:
0、1 对比换位,1、2 对比换位,确定 2
0、1 对比换位,确定 0、1
思路扩展:
尝试想象一下,当数组的数量为四个
0、1 对比换位,1、2 对比换位,2、3 对比换位,确定 3
然后再重复一下刚刚实现的经过
0、1 对比换位,1、2 对比换位,确定 2
0、1 对比换位,确定 0、1
至此,一种算法入门的排序思路已经出现,它被称为:冒泡排序 ~咕嘟咕嘟
根据思路扩展,尝试实现算法:
// 首先,写出第一轮循环对比:得到数组中最大值并移动到最右边
const arr = [9, 8, 7, 6]
const bubbleSort = (arr) => {
// 先把之前的对比的判断,把索引改成动态的
// if (arr[i] > arr[i + 1]) {
// ;[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]
// }
// 首先想到for循环。能写出来什么样呢
// for()
// 我们需要用一些数字。跟循环的次数有关
// 一般而言,都会拿数组的长度来用。这里,数组的长度有什么用处
// arr.length // 4
// for (let i = 0; i < ???; i++) {
// if (arr[i] > arr[i + 1]) {
// ;[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]
// }
// }
// 关键是,i 要小于几呢?那就先要确定,我们要对比多少次,然后再给出限制
// 这个对比的次数,要依据 < 思路扩展 > 中的第一轮对比!其中第一轮,经过了 3 次对比换位
// 又因为我们是从 0 开始的。所以,要拿到的数字是0、1、2,所以要小于3
// 数组的长度跟这个数字的关系就是 length - 1,这就是我们要小于的值
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
;[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]
}
}
return arr
// 如果从 1 开始,那就另一回事了
}
console.log(bubbleSort(arr)) // [ 8, 7, 6, 9 ]
这时候我们已经把最大的移动到了最右边,第一步完成了
然后呢?接下来,我们要对比前三个,不对比第四个了。这个怎么写啊
我们要让这个循环再来一遍。但是,循环次数要少一次。重要!!!
让循环再来一次,也就是说,让这个循环循环
const bubbleSort = (arr) => {
// for()
// 外边这个循环怎么加呢,要让里面的循环,走几轮呢?跟里面的循环有什么关系呢?
// 再一次,依据 < 思路扩展 > ,要让里面循环 3 轮,就能得到结果了
// 里面循环对比的次数不断减 1 的,那让外面的循环不断减 1,并让这个数字同步到里面对 i 的限制
// for(let j = ???; j >= 0; j--){
// for (let i = 0; i < arr.length - 1; i++) {
// if (arr[i] > arr[i + 1]) {
// ;[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]
// }
// }
// }
// 让外面的 j ,设定为里面的 i 的初始值,然后逐渐变小,最终等于 0,然后结束
for (let j = arr.length - 1; j >= 0; j--) {
for (let i = 0; i < j; i++) {
if (arr[i] > arr[i + 1]) {
;[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]
}
}
}
return arr
}
console.log(bubbleSort(arr)) // [ 6, 7, 8, 9 ]
主线代码完成
const bubbleSort = (arr) => {
for (let j = arr.length - 1; j >= 0; j--) {
for (let i = 0; i < j; i++) {
if (arr[i] > arr[i + 1]) {
;[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]
}
}
}
return arr
}
// 随便输入一些,看看效果
console.log(bubbleSort([543, 4, 76, 524, 24, 65, 23, 235, 3245])) // [ 4, 23, 24, 65, 76, 235, 524, 543, 3245 ]
后续优化:隔离数据源、减少非必要性能开销
const bubbleSort = (array) => {
const arr = [...array]
for (let j = arr.length - 1; j >= 0; j--) {
let swapped = false
for (let i = 0; i < j; i++) {
if (arr[i] > arr[i + 1]) {
;[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]
swapped = true
}
}
if (!swapped) break
}
return arr
}
完成。