快速排序
1.基本思想:给定基准值找到其正确索引位置,分治算法处理子序列。
2.整体实现过程:
- 选择一个基准值(这里选择最右边作为基准值)
- 遍历整个区间,每个数都和基准值作比较,并且发生一定的交换,遍历结束后,使得:<= 基准值的数都在基准值的左边;> 基准值的数都在基准值的右边
- 分治算法:分别对左右两个小区间进行同样的处理方式,直到小区间的size == 1(有序)或size == 0(实际不会走到)
3.用一个图来解释一下整个快排的处理过程:
4.了解了快排的整体过程,那么如何找到基准值的正确索引位置问题呢? 请看我滴详解partition过程:
partition分割过程有三种方法:
- 1.hover法
- 2.挖坑法
- 3.前后下标法,这种方法不常用。hover法和挖坑法思想类似,首先说说个人认为比较简单的挖坑法。
挖坑法:
首先记录基准值。
①一个下标从左边开始(begin),一个下标从右边开始
②过程中保证begin的左边都 <= 基准值,如果遇到不符合的情况,array[end]=array[begin]
end的右边都 >= 基准值,如果遇到不符合的情况,array[begin]=array[end]
③直到begin遇到end,把基准值放到begin(end)索引处
hover法:
5.java代码实现:
//快速排序,O(n*log(n)),不稳定,空间复杂度O(log(n))或O(n)
//选最边作为基准值时,数组已经有序或逆序,时间复杂度最坏O(n^2),例如12345,pivot=5
/*
1.选基准值
2.partition
3.分治算法处理左右两个小区间,直到size==1或size==0
*/
private static void quickSort(int[] array, int left, int right) {
if (left >= right) {
return;
}
int pivot = partition(array, left, right);
quickSort(array, 0, pivot - 1);
quickSort(array, pivot + 1, right);
}
//挖坑法
private static int partition(int[] array, int left, int right) {
int begin = left;
int end = right;
int pivot = array[end];
while (begin < end) {
while (begin < end && array[begin] <= pivot) {
begin++;
}
array[end] = array[begin];
while (begin < end && array[end] >= pivot) {
end--;
}
array[begin] = array[end];
}
array[begin] = pivot;
return begin;
}