快速排序是一種分治的排序算法。它將一個數組分爲兩個數組,將兩部分獨立地排序。
快速排序遞歸地將子數組a[lo..hi]排序,先用partition()方法將a[j]放到一個合適的位置,然後再用遞歸調用將其他位置的元素排序。
該方法的關鍵在於切分,這個過程使得數組滿足下面三個條件:
1.對於某個j,a[j]已經排定;
2.a[lo]到a[j - 1]中的所有元素都不大於a[j];
3.a[j + 1]到a[hi]的所有元素都不小於a[j]。
切分的一般策略是先隨意的取a[lo]作爲切分元素,即那個將會被排定的元素,然後我們從數組的左端開始向右掃描直到找到一個大於等於它的元素。再從數組的右端開始向左掃描直到找到一個小於等於它的元素
具體實現:
public static int partition(Comparable[] a, int lo, int hi){
Comparable v = a[lo];
int i = lo;
int j = hi + 1;
while (true){
while(less(a[++i], v)){
if(i == hi){
break;
}
}
while(less(v, a[--j])){
if(j == lo){
break;
}
}
if(j <= i){
break;
}
Example.exch(a, j , i);
}
Example.exch(a, j, lo);
return j;
}
public 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);
}
快速排序算法改進
1.切換到插入排序
(1)對於小數組,快速排序比插入排序慢;
(2)因爲遞歸,快速排序的sort()方法在小數組中也會調用自己。
因此,在排序小數組時應該切換到插入排序。
三向切分的快速排序
public static void threeWaySort(Comparable[] a, int lo, int hi){
if(hi <= lo){
return;
}
int lt = lo, i = lo + 1, gt = hi;
Comparable v = a[lo];
while(i <= gt){
int cmp = a[i].compareTo(v);
if(cmp > 0){
Example.exch(a, i, gt--);
}else if(cmp < 0){
Example.exch(a, i++, lt++);
}else{
i++;
}
}//現在a[lo..lt-1] < v = a[lt..gt] < a[gt + 1..hi]
sort(a, lo, lt - 1);
sort(a, gt + 1, hi);
}