快排版本1:最差O(n^2) 划分值很偏
总拿最后一个数做划分,划分好最后一个数和大于区的第一个数做交换,然后在小于等于5区域和大于5区域继续往复循环操作,都取各自的最后一个数作为基准数。
快排版本2:最差O(n^2) 划分值很偏
每次排序都能搞定一堆等于5的区域。只要最后一个数和大于区的第一个数做交换
然后左右侧以最后一个数作为基准数,继续做递归。
快排 【最好情况 几乎在中点】O(n*logn)
L到R随机选个数和最后位置做交换,拿最后位置做划分。
举例
L和R的索引分别是10和15
partition后就返回12和13,表示的是划分值区域的左边界和右边界
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 < 1swap(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};}