一、解释
在经典快速排序中,每次拿最后一个数来做比较,当数据样本大致有序时,每次都会比较N次,这时时间复杂度O(N*logN)的快排算法就会蜕变为O(N^2)的算法。
在算法设计中,通常为避免数据样本所带来的问题,会采用以下两种方法
*1、随机数方式(本算法中采用)
*2、hash函数方式
二、代码+注释
package algorithm_02;
import logarithmic_device.Sort_logarithmic_device;
/*
*
*快速排序中当数据样本基本有序时,常规排序操作 会是O(N^2)的时间复杂度
*所以采用随机快排方式 随机交换数组中一个数到最后一个 来进行partition 来尽量避免O(N^2)
*
*在算法设计中,通常为避免数据样本所带来的问题,会采用以下两种方法
*1、本算法中采用的随机数方式
*2、hash函数方式
*/
public class QuickSort {
public static void quickSort(int arr[]){
if (arr==null||arr.length<2) {
return;
}
quickSort(arr,0,arr.length-1);
}
public static void quickSort(int[] arr, int L, int R) {
if(L<R){
/**
* 在L-R区间随机找一个数 与数组最后一个数交换
* 来避免数据样本带来的问题(可能会形成O(N^2)的时间复杂度)
*/
Sort_logarithmic_device.swap(arr, (int)(L+Math.random()*(R-L+1)), R);
int bound[]=partition(arr, L, R);//返回等于比较值得区域
quickSort(arr, L, bound[0]-1);//左侧
quickSort(arr, bound[1]+1, R);//右侧
}
}
public static int[] partition(int arr[],int L,int R){
int less=L-1;
int more=R+1;
while(L<more){
if (arr[L]<arr[R]) {
//若当前数字小于比较数字 则将小范围前一位与当前数字交换 并且 小范围扩大一位 游标右移一位
Sort_logarithmic_device.swap(arr, ++less, L++);
}else if (arr[L]>arr[R]) {
//若当前数字比比较数字大 则与大范围得前一位交换 并且大范围扩大一位
Sort_logarithmic_device.swap(arr, L, --more);
}else{
//若相等 则游标右移 大范围小范围均不做变化
L++;
}
}
return new int[]{less+1,more-1};
}
public static void main(String[] args) {
int arr[]={1,0,-9,-9,-9,8,5,6,10,-2};
quickSort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}