快速排序要点总结
所谓快速排序,无非是用二分的思想,找到每一个元素应该在的位置,从而完成排序。
写算法最难的地方在于边界条件和特殊情况的判断。
先给出正确的写法:
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
int[] arr = new int[]{5,4,1,2,9,7,6,3,8};
quickSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr) {
quickSort(arr, 0, arr.length-1);
}
public static void quickSort(int[] arr, int left, int right) {
if (left > right) {
return;
}
// 选取第一个元素为枢轴元素,即本次排序中要把他放在正确的位置
int pivot = arr[left];
int temp;
int i = left, j = right;
while (i != j) {
while (j > i && arr[j] >= pivot) {
j--;
}
// 易错点,判断条件一定要加等号,保证i能往右走一步
while (i < j && arr[i] <= pivot) {
i++;
}
if (i != j ) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
temp = arr[i];
arr[i] = pivot;
arr[left] = temp;
// 递归地处理左边和右边
quickSort(arr, left, i-1);
quickSort(arr, i+1, right);
}
}
要点1:先从右往左,再从左往右
本次排序中选取第一个元素为枢轴元素,即本次排序中要把他放在正确的位置。一定要先让j递减,再让i递增,因为i的初始状态就是枢轴元素。如果选取最左边的数arr[left]作为基准数,那么先从右边开始可保证i,j在相遇时,相遇数是小于基准数的,交换之后temp所在位置的左边都小于temp。但先从左边开始,相遇数是大于基准数的,无法满足temp左边的数都小于它。所以进行扫描,要从基准数的对面开始。
要点2:注意每一次都要判断i!=j,保证i、j相遇时循环随时可以跳出
要点3:注意while循环中的等号
while (i < j && arr[i] <= pivot)
因为i是从枢轴元素开始的,要保证i能往右走一步,这个判断条件必须要加等号
要点4:注意调用函数的范围,防止数组下标越界
public static void quickSort(int[] arr) {
quickSort(arr, 0, arr.length-1);
}
arr[arr.length]可是取不到的哦~