交换排序详解
交换排序的核心逻辑非常纯粹:通过两个元素之间的比较与位置交换,让有序的序列逐渐浮现。
本篇将深度拆解:冒泡排序及其极致优化,以及快速排序的四种主流实现(Hoare 版本、挖坑法、前后指针法、非递归实现)。
一、冒泡排序
1.1 算法思想:气泡升腾的奥秘
冒泡排序模拟了水中气泡上升的过程。大的数值会通过相邻位置的比较,一层一层地往数组末尾浮动。
核心步骤:
- 比较相邻的两个元素。如果第一个比第二个大,就交换它们。
- 对每一对相邻元素做同样的工作,从第一对到最后一对。
- 每一轮结束,最大的数都会被挪到当前待排序列的最后一位。
- 重复上述步骤,直到没有任何一对数字需要比较。
1.2 为什么你的冒泡排序总是比别人慢?
很多教科书给出的冒泡排序是'死'的。如果数组已经有序了,它依然会傻傻地跑完所有循环。
极致优化思路: 设置一个标记。如果在一轮遍历中没有发生任何交换,说明数组已经有序,直接提前终止!
1.3 代码实现
void BubbleSort(int* a, int n) {
// 外层循环:控制排序的轮数
// 每执行完一轮,待排序序列中最大的那个数就会被'冒泡'到数组的最后一位
// n 个元素通常需要比较 n-1 轮
for (int i = 0; i < n; i++) {
// 【优化关键】:设置一个标记变量 flag
// 初始设为 0,假设这一轮遍历中没有发生任何交换(即数组已经有序)
int flag = 0;
// 内层循环:负责在当前待排序区间内进行相邻两数的比较
// 随着 i 的增加,数组末尾已经排好序的元素越来越多
// 因此内层循环的边界是 n - i - 1
for (int j = 0; j < n - i - 1; j++) {
// 如果前一个数比后一个数大,则说明顺序不对,需要交换
if (a[j] > a[j + ]) {
Swap(&(a[j]), &(a[j + ]));
flag = ;
}
}
(flag == ) ;
}
}


