`void quick_sort(int a[], int l, int r)
{
if(l >= r) return;
int i = l - 1, j = r + 1, x = a[l + r + 1 >> 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(a, l, i - 1), quick_sort(a, i, r);
}`
问题1:边界问题,为什么当quick_sort(a, l, i - 1), quick_sort(a, i, r);时,取x = a[l + r + 1 >> 1],当quick_sort(a, l, j), quick_sort(a, j + 1, r);时,取x = a[l + r >> 1]:
解答:
因为当 i 作为分界点时,需要确保 i 不会取到 l,否则左区间会变成空的,所以取x = a[l + r + 1 >> 1]这样靠右的中点,反之则是确保 j 不会取到 r。
问题2:为什么采用quick_sort(a, l, i - 1), quick_sort(a, i, r);而不是quick_sort(a, l, i), quick_sort(a, i+1, r);,j同理:
解答:
因为i是从左到右,当i最终停止时一定是大于等于中点的值的,也就是说i的位置的数一定属于右半部分,所以左半部分就是到i-1结束。j同理
问题3:为什么指针移动用l - 1和r + 1配合do while而不是直接用l和r配合while?
解答:
因为边界问题while会先判断再移动,就可能会产生,判断后移动导致两个指针越界错开,但是do while就会避免这样的问题。