冒泡排序正确循环边界为外层i从0到n-2,内层j从0到n-2-i;因需访问arr[j+1],故j上限为n-2-i而非n-1-i,避免越界。

冒泡排序的正确循环边界怎么写
很多人写的冒泡排序跑一遍就停了,或者多跑一轮导致越界,问题出在内外层循环的终止条件上。i 控制轮数,j 控制每轮比较范围,每轮结束后最大元素“冒”到末尾,所以下一轮 j 的上限要减一。
-
i从0到n-1(共n轮,但实际最多n-1轮就能排好) -
j从0到n-2-i,不是n-1-i—— 因为要访问arr[j+1],所以j+1 < n⇒j < n-1 - 如果用
for (int j = 0; j < n - 1 - i; j++),边界刚好卡住不越界
为什么 swap 后不加 break 就不是“优化版”冒泡
标准冒泡每轮都扫到底;所谓“优化”是指提前发现已有序时直接退出。但很多人只加了 if (swapped == false) break;,却忘了重置 swapped 标志位——结果第二轮就失效了。
- 必须在每轮开始前设
bool swapped = false; - 只有
swap发生时才置为true - 常见错误:把
swapped声明在循环外,或漏掉赋初值 - 这个优化对完全逆序数组没用,但对基本有序数据能显著减少比较次数
vector<int> 和 int[] 在实现时要注意什么
用 std::vector 写更安全,但新手常忽略 .size() 返回 size_t(无符号),和 int 混算会导致隐式转换问题,尤其在 n-1-i 中 i 是 int 时可能变成极大正数。
- 推荐统一用
size_t i = 0;,或强转:static_cast<int>(vec.size()) - 数组传参时,
int arr[]实际退化为指针,必须额外传size,不能用sizeof(arr)/sizeof(arr[0]) -
vector可直接用.size(),且支持at()做边界检查(调试时有用)
运行时崩溃或结果错乱的典型错误现象
报 EXC_BAD_ACCESS 或输出乱码,大概率是数组越界;结果部分有序、末尾元素错位,往往是内层循环少减了 1。
立即学习“C++免费学习笔记(深入)”;
- 错误写法:
for (int j = 0; j < n - i; j++)→ 访问arr[j+1]时越界 - 错误写法:
for (int i = 0; i < n; i++)+j < n - i→ 第一轮j最大为n-1,j+1就越界 - 用
gdb或AddressSanitizer能快速定位越界位置,比肉眼查快得多
边界计算看着简单,但 n、i、j 三者关系稍一松动就出事,手写时最好先在纸上画两轮索引变化再敲代码。











