冒泡排序需外层n-1轮、内层每轮范围递减,交换条件为arr[j] > arr[j+1](升序),且j+1 < n防越界。

冒泡排序的核心逻辑怎么写才不出错
冒泡排序本质是重复比较相邻元素并交换,让较大(或较小)的值像气泡一样“浮”到一端。关键不是背代码,而是理解每轮 for 循环的边界和交换条件。
- 外层循环控制“轮数”,共
n-1轮就够了(最后一轮只剩一个元素无需比较) - 内层循环控制“当前轮中比较的范围”,每轮后末尾已有序,所以每次上限减 1:用
j ,别写成 <code>j - 交换只在
arr[j] > arr[j + 1]时发生(升序),注意下标别越界——j + 1要小于n
手写时最容易踩的数组越界和索引错误
新手常把内层循环写成 for (int j = 0; j ,然后在循环里访问 <code>arr[j+1],导致访问 arr[n]——这是未定义行为,可能崩溃或输出乱码。
- 正确写法必须保证
j + 1 ,即 <code>j ;再结合每轮缩小范围,就是 <code>j - 如果用
std::vector,记得用.size()获取长度,并强转为int或用有符号类型比较,避免无符号整数下溢(比如0 - 1变成极大正数) - 调试时可在循环开头加
std::cout 快速定位越界位置
用 vector 还是原生数组?参数传递怎么选
对新手更安全的是传 std::vector<int>&</int>,避免指针和长度分离带来的管理负担;但如果练基本功,用原生数组要显式传长度,不能只传 int arr[](它会退化为指针,丢失大小)。
- 推荐函数签名:
void bubbleSort(std::vector<int>& arr)</int>或void bubbleSort(int arr[], int n) - 别写
void bubbleSort(int arr[])—— 编译器不检查长度,你无法知道数组多大 - 如果函数内需要拷贝一份做测试,用
std::vector<int> temp = arr;</int>,别用memcpy操作 vector 内部指针(不安全且没必要)
要不要加优化:提前终止的 flag 怎么设才有效
如果某轮没发生任何交换,说明已有序,可以提前退出。但 flag 的初始化和重置位置很关键,放错地方会让优化失效。
立即学习“C++免费学习笔记(深入)”;
- flag 必须在每轮外层循环开始前设为
false,并在发生交换时设为true - 检查时机在内层循环结束后:
if (!swapped) break; - 注意不要在内层循环里就 break 外层——C++ 没有标签 break,得靠 flag 控制
- 这个优化对已排序或近似有序数据明显,但最坏情况(逆序)下仍为 O(n²),别误以为加了 flag 就变快了
实际写的时候,先跑通无 flag 版本,再加 flag;测试用例至少包括空数组、单元素、已排序、完全逆序、含重复数这五种情况。边界比算法本身更容易出问题。










