无限循环情况
- x = q[l], x = q[r], x = q[(l+r)/2]
- 这看似有三种选择,实则只有两种x = q[l], x = q[r]
- 当只有两个元素时,x = q[(l+r)/2]的情况与x = q[l]相同
以j为划分时,x不能选q[r] (若以i为划分,则x不能选q[l])
假设 x = q[r]
关键句子quick_sort(q, l, j), quick_sort(q, j + 1, r);
由于j的最小值是l,所以q[j+1..r]不会造成无限划分
但q[l..j](即quick_sort(q, l, j))却可能造成无限划分,因为j可能为r
举例来说,若x选为q[r],数组中q[l..r-1] < x,
那么这一轮循环结束时i = r, j = r,显然会造成无限划分
错误如下
#include <iostream>
using namespace std;
const int N = 1000000 + 16;
int A[N];
void quick_sort(int A[], int l, int r) {
//循环结束
if (l >= r) {
return;
}
int i, j, x;
i = l - 1;
j = r + 1;
x = A[(i + j) / 2];
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(A, l, i);
quick_sort(A, i-1, r);
//改正
quick_sort(A, l, j);
quick_sort(A, j+1, r);
}
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &A[i]);
}
quick_sort(A, 0, n - 1);
for (int i = 0; i < n; i++) {
printf("%d ", A[i]);
}
return 0;
}