冒泡排序核心是外层i控制轮数(0到n-2),内层j遍历未排序部分(0到n-i-2),仅当arr[j]>arr[j+1]时交换;需设swapped标志提前终止,避免冗余轮次。

冒泡排序的核心逻辑怎么写才不出错
冒泡排序本质是重复遍历数组,两两比较相邻元素,把较大(升序)的“浮”到末尾。关键不是套模板,而是理解每轮 for 的边界和交换触发条件。
常见错误:内层循环上限写成 n 而非 n - i - 1,导致越界或重复比较;或者漏掉交换判断,变成无意义遍历。
- 外层
i控制轮数,从0到n-1 - 内层
j从0到n - i - 1,因为每轮后末尾i+1个元素已就位 - 只在
arr[j] > arr[j + 1]时交换,避免无谓操作
标准 C++ 实现(含完整可运行结构)
下面这段代码可在任何支持 C++11 的环境直接编译运行,不依赖额外库:
#include#include void bubbleSort(std::vector
& arr) { int n = arr.size(); for (int i = 0; i < n - 1; ++i) { for (int j = 0; j < n - i - 1; ++j) { if (arr[j] > arr[j + 1]) { std::swap(arr[j], arr[j + 1]); } } } } int main() { std::vector
nums = {64, 34, 25, 12, 22, 11, 90}; bubbleSort(nums); for (int x : nums) std::cout << x << " "; return 0; }
注意:std::swap 比手写临时变量更安全,尤其对自定义类型;用 std::vector 替代裸指针数组,避免内存管理干扰算法逻辑。
立即学习“C++免费学习笔记(深入)”;
如何提前终止优化性能
如果某轮遍历中一次交换都没发生,说明数组已有序,后续轮次可跳过。这是冒泡排序唯一实用的优化点。
- 加一个
bool swapped = false标志 - 每次交换时设为
true,内层循环结束后检查 - 若仍为
false,直接break外层循环 - 最坏时间复杂度仍是 O(n²),但对已排序或近似有序数据能降到 O(n)
为什么不用 std::sort?什么场景下真得手写
std::sort 是混合排序(introsort),平均 O(n log n),远快于冒泡。除非以下情况,否则别手写冒泡:
- 教学演示:必须暴露比较/交换过程
- 嵌入式极简环境:连 STL 都没启用,只能用原始数组 +
int类型 - 调试需要:比如在排序过程中插入断点观察每步状态
实际项目里硬上冒泡,基本等于主动给自己加延迟——特别是当 n > 100 时,性能落差会非常明显。











