图解题库 / 排序 · 冒泡

冒泡排序

简单 含交互动画

学完这道你应该能: 说清它为什么用「冒泡」,而不是死记步骤; 合上页面,自己默写出核心代码; 用 30 秒把思路讲清楚。

题目描述

反复扫描数组,相邻元素两两比较,左 > 右就交换。一趟下来最大的沉到末尾。

输入 = [5, 2, 4, 1, 3]
输出 = [1, 2, 3, 4, 5]

思路解析

从左到右,比较 (0,1)、(1,2)…每次把较大的换到右侧。一整趟后,最大值一定到了最右;下一趟范围缩小一格,重复。

比较 5、2 · 5 大 → 交换:第 1 趟开始。比相邻的 5 和 2,5 更大,交换它俩。

比较 5、4 · 交换:5 继续和右边的 4 比,5 大,交换。大的数像气泡一样被一路带着往右走。

比较 5、1 · 交换:5 和 1 比,交换。

比较 5、3 · 交换:5 和最后的 3 比,交换。5 到达最右端。

第 1 趟结束 · 5 归位:第 1 趟走完,最大的 5 冒到最右、已归位(绿色)。下一趟只需在前 4 个里冒。

第 2 趟 · 4 归位:第 2 趟在前 4 个里冒泡(过程同理),4 归位。每趟右边已排好的区域(绿色)扩大一格。

第 3 趟 · 3 归位:第 3 趟在前 3 个里冒泡:比 2 和 1,交换 → [1,2,3],3 归位

第 4 趟 · 全部有序:第 4 趟比 1、2 已有序,最终 [1,2,3,4,5] 全部归位。

冒泡是理解"排序"的最好起点:通过相邻交换逐步消除逆序对。它和选择、插入并称三大基础 O(n²) 排序。

参考代码(Python)

Python
1n = len(nums)
2for i in range(n - 1):                 # 趟数
3    swapped = False
4    for j in range(n - 1 - i):         # 已归位的不用再比
5        if nums[j] > nums[j+1]:        # 相邻逆序
6            nums[j], nums[j+1] = nums[j+1], nums[j]
7            swapped = True
8    if not swapped: break              # 一趟没换=已有序

复杂度分析

  • 时间复杂度:O(n²) —— 最坏/平均;已有序 O(n)
  • 空间复杂度:O(1) —— 原地交换

套路模板

记住骨架:外层趟数、内层相邻比较、右边 i 个不再动。它是后面理解"为什么快排/归并更快"的对照基准。

Python
1for i in range(n - 1):
2    for j in range(n - 1 - i):           # 右边 i 个已归位
3        if a[j] > a[j+1]: swap(j, j+1)   # 相邻逆序就换

易错点

  • 内层 range(n) → ✅ range(n-1-i)(右边已归位的不用再比,也避免 j+1 越界)
  • 用 >= 比较 → ✅ 严格 > 才交换(相等不换才能保证"稳定")

以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握

下一题 →选择排序 ← 返回题库