前言:
快速排序是C.A.R Hoare于1960年发明的。基本思想也是分治。快速排序不需要额外的空间,是原地排序,时间复杂度是O(NlgN),
快速排序快在元素之间是跳跃比较,比较的次数将会减少,内循环短小。在实际应用中,比其他排序算法都要快得多。
快速排序:
对于待排数组a,长度为N,
1,首先,选定一个元素作为固定的比较对象,我们称之为基准元素 v。选定两个变量 i , j作为索引 ,开始时i=0,j=N-1;
2,从 j 开始向前搜索,找到第一个a[ j ]<v ,从 i 开始向后搜索,找到第一个a[ i ] > v, 交换a[ i ]和a[ j ];
3,当i >= j时退出,退出后将 v 归位,即将 v 和 a[ j ] 互换
此时 v 将原数组切分成两个子数组,左边都是比它小的元素,右边都是比它大的元素。
4,对 v左右两边的数组重复以上步骤,直到每组只剩一个元素。
/**
* 快速排序
* 最快的排序算法
* 平均比较次数2NlogN,无需额外空间
* 之所以快是因为和定值比较,跳跃交换,交换和比较的次数变少
* @author CANAAN
*
*/
public class QuickSort {
public static void sort(Comparable[] a){
StdRandom.shuffle(a); //防止出现倒序等时间复杂度为平方的序列
sort(a,0,a.length-1);
}
private static void sort(Comparable[] a, int lo, int hi) {
if(hi <= lo) //比较完时退出
return;
int j = partition(a,lo,hi);
sort(a,lo,j-1);
sort(a,j+1,hi);
}
private static int partition(Comparable[] a, int lo, int hi) {
int i = lo,j = hi+1; //i从第一个元素开始,j从最后一个元素开始
while(true){
while(less(a[++i], a[lo])){ //比较前先计算++
if(i == hi) break;}
while(less( a[lo],a[--j])){
if(j == lo) break; }
if(i>=j) break;
exch(a, i, j); //a[i]>基准,a[j]<基准,交换
}
exch(a,lo,j); //将基准元素调换到j处,此时左边都是小于a[j]的,右边都是大于a[j]的
return j;
}
private static boolean less(Comparable v, Comparable w){ //比较v是否小于w
return v.compareTo(w) < 0;
}
private static void exch(Comparable[] a, int i,