![](https://file.jishuzhan.net/article/1769641797245472770/ded8bde0e0d9ac102d5b2bf9130dc678.webp)
快排版本1:最差O(n^2) 划分值很偏
总拿最后一个数做划分,划分好最后一个数和大于区的第一个数做交换,然后在小于等于5区域和大于5区域继续往复循环操作,都取各自的最后一个数作为基准数。
![](https://file.jishuzhan.net/article/1769641797245472770/e5a7751b802a22c11b09f65294aab9cb.webp)
快排版本2:最差O(n^2) 划分值很偏
每次排序都能搞定一堆等于5的区域。只要最后一个数和大于区的第一个数做交换
![](https://file.jishuzhan.net/article/1769641797245472770/989d5a84c2099b5c7674d3f8c0a8c867.webp)
![](https://file.jishuzhan.net/article/1769641797245472770/81f7c85bf95f35050571bf39dc48b230.webp)
然后左右侧以最后一个数作为基准数,继续做递归。
![](https://file.jishuzhan.net/article/1769641797245472770/3f3dda6381a8516d1e9685438d2d05f9.webp)
快排 【最好情况 几乎在中点】O(n*logn)
L到R随机选个数和最后位置做交换,拿最后位置做划分。
![](https://file.jishuzhan.net/article/1769641797245472770/d2af19101e54c30e30bfe546cc7003de.webp)
举例
L和R的索引分别是10和15
![](https://file.jishuzhan.net/article/1769641797245472770/4e54f018c57ac529a284adeb8e5740f0.webp)
partition后就返回12和13,表示的是划分值区域的左边界和右边界
![](https://file.jishuzhan.net/article/1769641797245472770/50b2c5798a890b97803c03b4cf96a14d.webp)
![](https://file.jishuzhan.net/article/1769641797245472770/42d58c3335b930e5a75802e86c887c59.webp)
![](https://file.jishuzhan.net/article/1769641797245472770/0c14ff629c7b86599bb90c27427dfe19.webp)
public int[] sortArray(int[] nums) {
if(nums == null || nums.length < 2){
return nums;
}
quickSort(nums,0,nums.length - 1);
return nums;
}
//交换位置
public void swap(int[] nums,int L,int R){
int temp = 0;
temp = nums[L];
nums[L] = nums[R];
nums[R] = temp;
}
// 快排
public void quickSort(int[] arr,int L,int R){
if(L < R){
// *精华!随机数和最后一个数做交换 随机数:0 <= r < 1
swap(arr,L + (int)(Math.random() * (R - L + 1)),R);
// 拿L和R范围上 以及我选出来的最后一个位置上 做partition
// 返回数组长度一定是2,中间排好序的左边界和右边界
int[] p = partition(arr,L,R);
// p[0]是等于区域的左边界,p[0]-1就是小于区域右边界
quickSort(arr,L,p[0]-1);
// p[1]是等于区域的右边界,p[1]+1就是大于区域左边界
quickSort(arr,p[1]+1,R);
}
}
public int[] partition(int[] arr,int L,int R){
// <区右边界
int less = L - 1;
// <区左边界
int more = R;
// arr[L]表示当前数的位置 还没碰上右边界的第一个数 排序
while(L < more){
if(arr[L] < arr[R]){
swap(arr,++less,L++);
}else if(arr[L] > arr[R]){
// >区左扩
swap(arr,--more,L);
}else{
L++;
}
}
// 都做完后,最后一个数和大于区第一个做交换
swap(arr,more,R);
// 返回中间排好序的左边界和右边界
return new int[] {less + 1,more};
}