/**
* 快速排序3.0 —— 随机快排,时间复杂度收敛于 O(NlogN)
*/
public class QuickSort {
/**
*
* @param arr 需要排序的数组
* @param L 需要排序部分的左边界
* @param R 需要排序部分的右边界
*/
public static void process(int[] arr,int L,int R){
if(L<R){
//在L,R范围上随机选择一个数,放在R位置上,把它作为划分值
// Math.random() 返回 [0,1) 的数
// 所以这个数的范围是 [L,R]
int p = L + (int) (Math.random()*(R-L+1));
//把这个随机数交换到R位置上
swap(arr,p,R);
//以R位置上的数作为划分值,进行分组 < == > 三个区域
int[] equalRange = partition(arr,L,R);
//返回的数组是 等于划分值区域 的左右边界
//对该区域的左右两部分再次进行处理
process(arr,L,equalRange[0]-1);
process(arr,equalRange[1]+1,R);
}
}
//以R位置上的数作为划分值 <arr[R] ==arr[R] >arr[R]
public static int[] partition(int[] arr,int L,int R){
int less = L-1; //小于区右边界
int more = R+1; //大于区左边界
int curr = L;
while(curr < more){
//当前数小于划分值时,当前数与小于区指针的下一位交换,小于区向右扩一位,当前数跳下一位
if(arr[curr]<arr[R]){
swap(arr,++less,curr++);
}else if(arr[curr]>arr[R]){ 当前数大于划分值,当前数和大于区指针的前一位交换,大于区向左扩一位,当前数位置不变(因为交换过来的数是未知的数)
swap(arr,--more,curr);
}else {
curr++;//当前数等于划分值,当前数往后跳一位
}
}
return new int[] {less+1,more-1};
}
private static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] test = {2,5,1,32,51,11,23};
process(test,0,test.length-1);
for (int i : test) {
System.out.println(i);
}
}
}
随机快速排序
最新推荐文章于 2024-07-28 22:35:47 发布