0785-快速排序
题目描述
关系
内容
问题分析
思路分析
执行流程设计
总结
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int a[N];
void quick_sort(int l, int r) {
if (l >= r) return;
int x = a[(l + r) >> 1], i = l - 1, j = r + 1;
while (i < j) {
do i++; while (a[i] < x);
do j--; while (a[j] > x);
if (i < j) swap(a[i], a[j]);
}
quick_sort(l, j);
quick_sort(j + 1, r);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
quick_sort(0, n - 1);
for (int i = 0; i < n; i++) cout << a[i] << " ";
return 0;
}
循环结束时,i >= j
正常情况下,按照循环不变式,我们应该会觉得结果已经显然了
因为i >= j,q[l..i] <= x, q[j..r] >= x
所以按照j来划分的话,q[l..j] <= x, q[j+1..r] >= x是显然的
可是,最后一轮循环有点特殊,因为最后一轮循环的if语句一定不会执行
因为最后一轮循环一定满足 i >= j,不然不会跳出while循环的,所以if语句一定不执行
正确分析:
由于最后一轮的if语句一定不执行
所以,只能保证:
q[l..i-1] <= x, q[i] >= x
q[j+1..r] >= x, q[j] <= x
i >= j
由q[l..i-1] <= x,i >= j(i-1 >= j-1) 和 q[j] <= x 可以得到 q[l..j] <= x
又因为q[j+1..r] >= x
所以,q[l..j] <= x,q[j+1..r] >= x,问题得证
总结:只有最后一轮循环结束时,循环不变式不成立,其余的循环都是成立的
但最终要求的问题还是解决了
注意:循环结束时要记得检查是否存在数组越界/无限划分的情况
所以还需要证明 j 最终的取值范围是[l..r-1](即不存在n划分成0和n的无限划分情况),分析过程在分析5