思想:
改进快排,不再总是以最后一个数作为基准,而是随机选取一个数作为基准,将其与最后一个位置互换,再进行快排。
时间复杂度 O(N*logN)
public class QuickSort {
/**
* 若数组为空或仅有一个元素,不用排序,直接返回
* @param arr 需要排序数组
*/
public static void quickSort(int[] arr){
if(arr == null || arr.length < 2 ){
return;
}
quickSort(arr, 0, arr.length -1);
}
/**
* 随机选取一个位置的元素作为基准与最后一个位置互换,
* 然后将比基准小的放在左边,比基准打的放在右边,递归进行
* @param arr 待排数组
* @param left 左临界
* @param right 右临界
*/
public static void quickSort(int[] arr, int left, int right){
if(left < right){
swap(arr, 1 + (int)(Math.random() * (right - left + 1)), right);
int[] p = partition(arr, left, right);
quickSort(arr, left, p[0] - 1);
quickSort(arr, p[1] + 1,right);
}
}
/**
*
* @param arr 待排数组
* @param left 左边界
* @param right 右边界
* @return 返回一个包含两个元素的int[],
* 第一个元素表示基准元素的左边界,第二个元素表示基准元素的右边界
*/
private static int[] partition(int[] arr, int left, int right){
int less = left - 1;//less表示比基准元素小的范围,left为当前所指
int more = right;//right表示基准元素位置,more表示不确定位置
while(left > more){
if(arr[left] < arr[right]){
swap(arr, ++less, left++);
}else if(arr[left] > arr[right]){
swap(arr, left, --more);
}else{
left++;
}
}
swap(arr, more, right);
return new int[]{less+1, more};
}
private static void swap(int[] arr, int i, int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}