快速排序
快速排序是 Hoare 于 1962 年提出的一种二叉树结构的交换排序方法。其核心思想是分治:任取待排序序列中的某元素作为基准值,将集合分割成两子序列,左子序列所有元素均小于基准值,右子序列所有元素均大于基准值,然后对左右子序列重复该过程,直到所有元素排列在相应位置上。
1. Hoare 版本
Hoare 分区方案是快速排序最经典的实现方式。简单来说,就是选定一个基准值(通常选第一个),通过两个指针从两端向中间扫描,将比基准小的放左边,比基准大的放右边。
以数组 [6, 1, 2, 7, 9, 3, 4, 5, 10, 8] 为例,假设 6 为基准。左边找大,右边找小,找到后互换。一趟下来,6 的左边都比它小,右边都比它大。随后以 6 为分界线,递归处理左右区间,这就像一棵二叉树的构建过程。
基础代码实现
void QuickSort(int* a, int left, int right) {
if (left >= right) return; // 区间不存在时直接返回
int keyi = left;
int begin = left;
int end = right;
while (begin < end) {
// 从右向左找小于基准的值
while (begin < end && a[end] >= a[keyi]) {
end--;
}
// 从左向右找大于基准的值
while (begin < end && a[begin] <= a[keyi]) {
begin++;
}
Swap(&a[begin], &a[end]);
}
// 将基准放到正确位置
Swap(&a[keyi], &a[end]);
// 递归排序子数组
QuickSort(a, left, end - 1);
QuickSort(a, end + 1, right);
}
为什么右边先走?
这是一个常见的面试考点。如果左边先走,当遇到比基准大的元素停止,而右边还没找到比基准小的元素时,可能会发生 的情况,导致死循环或逻辑错误。右边先走能确保 最终停在比基准小的位置,保证 的安全性。


