1. 程式人生 > >快速排序—QuickSort

快速排序—QuickSort

快速排序是一個十分著名的排序演算法,也是O(n log n)級別的排序演算法。

其思想就是把陣列分為三個部分,v——小於v的部分———大於v的部分。

這樣分類後,再分別對小於v的部分,大於v的部分再進行一次遞迴,就完成了排序。

我們把第一個元素作為v ,   varr[i] l為陣列的第一個位置;

把除去v的區間中的第一元素的索引設為 i;

j 為小於v的區間的右閉區間,那麼在開始時,[l+1,j]這個區間是為空的,初始時設 j = l;

if  arr[i] < v 那麼 i 位置上的元素就屬於 "小於v的區間",即上圖中的橙色部分,此時arr[i]將劃入橙色區間。並且arr[i]與arr[j+1]位置互換,此時橙色區間內將新增一個成員,橙色右區間也隨之增加,即j++; (這個操作,初始沒有遇到不小於v的元素時,即元素自己與自己交換,因為此時i=j+1;在遇到不小於v的元素後,i變化,j卻不一定變化。大家可動手在草稿上演示)

else 如果arr[i]不小於v,則自動歸於大於v的區間,即綠色部分,不需要操作。

最後,把v回到兩個區間的中間位置,這樣就完成了一次排序。

根據這個思想,我們寫出程式碼如下:

   private static int partition(Comparable[] arr, int l, int r){
        Comparable v = arr[l];
       
        int j = l; // arr[l+1...j] < v ; arr[j+1...i) > v
        for( int i = l + 1 ; i <= r ; i ++ )		
            if( arr[i].compareTo(v) < 0 ){  
                swap(arr, j+1, i);  
                j++; 
                SortTestHelper.printArray(arr);
            }
        	SortTestHelper.printArray(arr);
        
        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;
    }