雙路快速排序算法是随機化快速排序的改進版本,partition 過程使用兩個索引值(i、j)用來周遊數組,将 <v 的元素放在索引i所指向位置的左邊,而将 >v 的元素放在索引j所指向位置的右邊,v 代表标定值。
時間和空間複雜度同随機化快速排序。 對于有大量重複元素的數組,如果使用上一節随機化快速排序效率是非常低的,導緻 partition 後大于基點或者小于基點資料的子數組長度會極度不平衡,甚至會退化成 O(n*2) 時間複雜度的算法,對這種情況可以使用雙路快速排序算法。
使用兩個索引值(i、j)用來周遊我們的序列,将 <=v 的元素放在索引 i 所指向位置的左邊,而将 >=v 的元素放在索引 j 所指向位置的右邊,平衡左右兩邊子數組。

源碼包下載下傳:Download
package runoob;
/**
* 雙路快速排序
*/
public class QuickSort2Ways {
//核心代碼---開始
private static int partition(Comparable[] arr, int l, int r){
// 随機在arr[l...r]的範圍中, 選擇一個數值作為标定點pivot
swap( arr, l , (int)(Math.random()*(r-l+1))+l );
Comparable v = arr[l];
// arr[l+1...i) <= v; arr(j...r] >= v
int i = l+1, j = r;
while( true ){
while( i <= r && arr[i].compareTo(v) < 0 )
i ++;
while( j >= l+1 && arr[j].compareTo(v) > 0 )
j --;
if( i > j )
break;
swap( arr, i, j );
i ++;
j --;
}
swap(arr, l, j);
return j;
}
//核心代碼---結束
// 遞歸使用快速排序,對arr[l...r]的範圍進行排序
private static void sort(Comparable[] arr, int l, int r){
if (l >= r) {
return;
int p = partition(arr, l, r);
sort(arr, l, p-1 );
sort(arr, p+1, r);
public static void sort(Comparable[] arr){
int n = arr.length;
sort(arr, 0, n-1);
private static void swap(Object[] arr, int i, int j) {
Object t = arr[i];
arr[i] = arr[j];
arr[j] = t;
// 測試 QuickSort
public static void main(String[] args) {
// 雙路快速排序算法也是一個O(nlogn)複雜度的算法
// 可以在1秒之内輕松處理100萬數量級的資料
// Quick Sort也是一個O(nlogn)複雜度的算法
int N = 1000000;
Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);
sort(arr);
SortTestHelper.printArray(arr);
}