相邻比较
左边更大才交换;相等时不交换,因此能保留相等元素的原顺序。
选一个算法,先预测,再点「下一步」。
比较相邻的两个数,让大的数一步步向右走。
左边更大才交换;相等时不交换,因此能保留相等元素的原顺序。
每轮把当前最大值送到右端,绿色区间里的数已经在最终位置。
所有相邻元素已经满足升序关系,可以直接结束。
复杂度 最好 O(n),平均与最坏 O(n²);额外空间 O(1)。
[5,3,4,1,2]描边是本步操作,绿色是已有序区间。下方是下标,柱高表示绝对值。
每轮比较相邻元素,把当前最大的数送到右侧。
每轮比较相邻元素,把当前最大的数送到右侧。
比较相邻的 5 和 3。
左边更大,交换两个元素。
比较相邻的 5 和 4。
左边更大,交换两个元素。
比较相邻的 5 和 1。
左边更大,交换两个元素。
比较相邻的 5 和 2。
左边更大,交换两个元素。
本轮结束,下标 4 的数已到最终位置。
比较相邻的 3 和 4。
比较相邻的 4 和 1。
左边更大,交换两个元素。
比较相邻的 4 和 2。
左边更大,交换两个元素。
本轮结束,下标 3 的数已到最终位置。
比较相邻的 3 和 1。
左边更大,交换两个元素。
比较相邻的 3 和 2。
左边更大,交换两个元素。
本轮结束,下标 2 的数已到最终位置。
比较相邻的 1 和 2。
本轮结束,下标 1 的数已到最终位置。
整轮没有交换,剩余区间也有序,可以提前结束。
排序完成。右侧已排好区间逐轮扩展到整个数组。
比较 0 次 · 写入 0 次(交换计 2 次写入)
最多 12 个 -99~99 的整数,用逗号或空格分隔;留空表示空数组。
循环不变量 每轮结束,右侧已排序区间里的数都在最终位置。
这里展示算法的核心思路,可在 src/baseSort/bubbleSort.ts 中自己实现一次。
function bubbleSort(arr: number[]): number[] {
for (let i = 0; i < arr.length - 1; i++) {
let swapped = false
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
;[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
swapped = true
}
}
if (!swapped) break
}
return arr
}输入 [1, 2, 3, 4, 5],先预测比较次数,再换例子验证。为什么一轮没有交换就能结束?
想自己写一次:打开 practice/algorithms.ts,补全 bubbleSort。运行下方命令,保存后会自动检查;未实现时测试失败是正常的。
pnpm practice:watch --grep bubbleSort每次只学一个:能解释每一步,再试着不看答案写出来。 继续浏览项目算法索引 →