-
得出结论:
如果选取最左边的数arr[left]作为基准数,那么先从右边开始可保证i,j在相遇时,相遇数是小于基准数的,交换之后temp所在位置的左边都小于temp。但先从左边开始,相遇数是大于基准数的,无法满足temp左边的数都小于它。所以进行扫描,要从基准数的对面开始。(注:左右相对来说,也可前后)
-
代码验证:
现选取最左边的数arr[left]作为基准数,即从右边开始扫描(哨兵j 先出动)
/**
* 实现快速排序: 基准数归位的过程
*
* @param arr
* @param left
* @param right
*/
public void quickSort(long[] arr, int left, int right) {
int i = 0;
int j = 0;
long pivot = 0;
long tmp = 0;
if(left >= right) {
return;
}
i = left;
j = right;
// refer存储基准数(初始化为数组第一个数,即左边)
pivot = arr[left];
// 当i = j (即相遇)时跳出循环
while (i < j) {
// 注意找的顺序,右边扫描
// 先从右往左找(找到小于基准数)
while (i < j && pivot <= arr[j]) {
// 往左找
j--;
}
// 再从左往右找(找到大于基准数)
while (i < j && pivot >= arr[i]) {
// 往右找
i++;
}
// 当i 与 j 没有相遇
if (i < j) {
// 交换两个数的位置
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
// 此时i = j 相遇了
// 最终将基准数的位置与i=j相遇的位置交换
arr[left] = arr[i];
// 基准数归位
arr[i] = pivot;
// 递归排序,对左边的子数组进行快速排序
quickSort(arr,left, i - 1);
// 对右边的子数组进行快速排序
quickSort(arr,i + 1, right);
}