冒泡排序(Bubble Sort)是最直观的排序算法之一:它反复扫描序列,依次比较相邻的两个元素,如果顺序错误就把它们交换过来。每一轮扫描结束后,未排序部分中最大的元素就像水中的气泡一样“浮”到未排序区间的末尾,因此得名。
对长度为 n 的序列,冒泡排序的执行过程是:
(0,1)、(1,2)、…、(n-2,n-1) 相邻元素对,把最大值换到下标 n-1;柱子颜色就是状态语言(页面右侧也有图例):
动画下方有一行实时解说(如 a[2] > a[3],交换 9 ↔ 1),结束时汇总总比较次数与交换次数,可以直观感受 O(n²) 的比较规模;右侧滑块可调节播放速度。
| 项目 | 复杂度 | 说明 |
|---|---|---|
| 平均/最坏时间 | O(n²) | 比较次数固定为 n(n-1)/2 量级 |
| 最好时间 | O(n) | 序列本身有序时,一轮无交换即提前结束(需交换标志优化) |
| 空间 | O(1) | 只需常数个辅助变量,原地排序 |
| 稳定性 | 稳定 | 相等元素不发生交换,相对次序保持不变 |
#include <iostream>
#include <vector>
#include <utility> // std::swap
using namespace std;
// 冒泡排序:带提前退出优化的写法
void bubbleSort(vector<int>& a) {
int n = a.size();
for (int i = 0; i < n - 1; i++) { // 最多 n-1 轮
bool swapped = false;
for (int j = 0; j + 1 < n - i; j++) { // 未排序区间内两两比较
if (a[j] > a[j + 1]) {
swap(a[j], a[j + 1]); // 大的往后冒
swapped = true;
}
}
if (!swapped) break; // 本轮无交换 → 已有序,提前结束
}
}
int main() {
vector<int> a = {5, 2, 9, 1, 7, 3, 8, 4};
bubbleSort(a);
for (int x : a) cout << x << ' '; // 输出:1 2 3 4 5 7 8 9
cout << endl;
return 0;
}
冒泡排序时间复杂度是 O(n²),在大数据量下远慢于快速排序、归并排序等 O(n log n) 算法,实际工程中很少直接使用。但它交换相邻元素的形式非常简单,是理解排序过程与复杂度分析的最佳入门案例;在 CSP-J 入门阶段,也常作为「逐轮模拟」类题目的基础套路出现。