C++怎么实现冒泡排序_C++基础算法教程【入门】

2次阅读

外层循环上限为n-1,内层上限为n-1-i;i从0开始控制轮数,j从0开始遍历未排序部分,每轮后最大元素沉底,边界动态收缩。

C++怎么实现冒泡排序_C++基础算法教程【入门】

冒泡排序的正确循环边界怎么写

写错 ij 的上限是初学者最常触发越界或漏排序的原因。外层循环控制轮数,最多 n-1 轮;内层比较相邻元素,每轮末尾的元素已就位,所以边界要动态收缩。

  • 外层用 for (int i = 0; i ,不是 <code> —— 第 <code>n 轮没意义
  • 内层用 for (int j = 0; j ,不是 <code> —— 否则每次都会访问到已排好序的末尾位置,可能越界(尤其当 <code>n == 1
  • 如果用 std::vector,记得用 .size() 并转成 int,否则 size_t 和负数相减会绕回极大值,直接崩

swap 函数该不该手写

std::swap 是安全且高效的默认选择,手写容易出错,尤其涉及指针、自定义类型或移动语义时。

  • 基础类型(intdouble)用 std::swap 没开销,编译器会优化成寄存器交换
  • 别写三变量交换(tmp = a; a = b; b = tmp;),既啰嗦又掩盖了意图;更别用异或技巧(a ^= b ^= a ^= b),对非整型不适用,且违反序列点规则,c++17 后可能未定义行为
  • 如果容器元素是自定义类,确保它支持移动或拷贝——std::swap 会自动优选移动构造/赋值,比手写更鲁棒

提前退出(优化版)加不加判断

加,但只在确定数据可能部分有序时才值得。纯教学或小数组(n )可省略,否则空跑 <code>n² 次毫无必要。

  • 声明一个 bool swapped = false,每次成功交换就置 true
  • 内层循环结束后检查:若 !swapped,直接 break 外层循环
  • 注意:这个优化不影响最坏时间复杂度(仍是 O(n²)),但最好情况从 O(n²) 降到 O(n)
  • 别在每轮都清零 swapped 后立刻设为 false —— 顺序错了会导致提前退出失效

vector 和 int[] 的传参差异

std::vector 默认是值拷贝,排序函数里改的是副本,原数组不变;而裸数组传参本质是传指针,改的是原内存。

立即学习C++免费学习笔记(深入)”;

  • 想原地排序 vector,必须用引用:参数写成 std::vector<int>& arr</int>
  • 裸数组如 int arr[10],函数参数写 int arr[]int* arr 效果一样,但无法在函数内用 sizeof(arr) 得到长度,得额外传 size
  • 混用时容易踩坑:比如把 vector.data() 传给期望 int* 的函数,没问题;但反过来把 &arr[0] 传给期望 std::vector& 的函数,编译不过

冒泡排序本身逻辑简单,但边界、传参、交换方式这些细节一旦写错,调试时现象往往很隐蔽:有时少排一个数,有时程序卡死,有时只在 Release 模式下出错。真正要注意的不是“怎么写出来”,而是“为什么这里必须这么写”。

text=ZqhQzanResources