算法
(1)快速排序的核心思想也是分治法,分而治之。它的实现方式是每次从序列中选出一个基准值,其他数依次和基准值做比较,比基准值大的放右边,比基准值小的放左边,然后再对左边和右边的两组数分别选出一个基准值,进行同样的比较移动,重复步骤,直到最后都变成单个元素,整个数组就成了有序的序列。
代码1-双边扫描
public void quickSort2(int[] arr, int left, int right){
if(left < right){
int pivotIndex = quick2(arr, left, right);
quickSort2(arr, left, pivotIndex - 1);
quickSort2(arr, pivotIndex + 1, right);
}
}
private int quick2(int[] arr, int left, int right) {
int pivot = arr[left];
int i = left;
int j = right;
while (true){
// i <= j 防止出现i=j 的情况;以及最终要的数组循环执行会越界 i++;
while ( i <= j && arr[i] <= pivot){ //error: arr[i] < pivot
i++;
}
while ( i <= j && arr[j] >= pivot){
j--;
}
// 及时退出,防止执行下一步的交换
if(i > j){
break;
}
// 指针卡住了,交换一下位置,继续
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// j 已经移到到 i的左边了
arr[left] = arr[j];
arr[j] = pivot;
return j;
}
代码2-单边扫描
(1)i++的位置影响了整个过程。
public void quickSort1(int[] arr, int left, int right){
if(left < right){
int pivotIndex = quick1(arr, left, right);
quickSort1(arr, left, pivotIndex - 1);
quickSort1(arr, pivotIndex + 1, right);
}
}
private int quick1(int[] arr, int left, int right) {
int pivot = arr[left];
int i = left; //error: left +1
for(int j = left + 1; j <= right; j++){
if(arr[j] < pivot){
i++;
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
// i++;
}
}
arr[left] = arr[i];
arr[i] = pivot;
return i;
}
代码2-2单边扫描
private int quick2(int[] arr, int left, int right) {
int pivot = arr[left];
int i = left+1;
for (int j = i; j <= right; j++){
if(arr[j]<pivot){
if(j!=i){
int tmp = arr[j];
arr[j] = arr[i];
arr[i] = tmp;
}
i++;
}
}
i--;
arr[left] = arr[i];
arr[i] = pivot;
return i;
}