1. 程式人生 > >資料結構與演算法之快速排序

資料結構與演算法之快速排序

快速排序顧名思義,在大部分情況下都能快速的將資料進行排序。百度百科快速排序的定義:通過一趟排序將要排序的資料分成獨立的兩部分,其中一部分的資料比另一部分的所有資料都要小,然後再按照這個方法對這兩部分進行快速排序,排序以遞迴進行,從而達到將整個資料變成有序序列。快速排序的平均執行時間是O(N log N)。

從快速快速的定義可知,排序是將資料分成兩部分,因此選擇切分資料的中數非常重要,否則兩部分的資料大小可能非常不均勻。

常用的分割策略:

  1. 隨機選取中數;
  2. 三數中值分割法;在實際運用中通常是取陣列的第一個值和中間值以及末尾值三者中間的中間數作為區分整個陣列的中數。

另外在實際的運用中發現對於資料量比較小的陣列使用插入排序更有效,因此需要根據資料量分別處理。

快速排序的程式碼例項:

package structures.arithmetic;

/**
 * 快速排序
 */
public class QuickSort {
    /**
     * 根據值大小確認使用插入排序還是分組遞迴排序
     */
    private final static int count = 10;

    /**
     * 快速排序
     * @param a 陣列
     * @param left 左側位置
     * @param right 右側位置
     * @param <AnyType> 型別
     */
    public static <AnyType extends Comparable<? super AnyType>> void quickSort(AnyType[] a, int left, int right){
        if(left+count<right){
            AnyType centureValue = media3(a, left, right); 
            int i=left, j=right-1;
            for(;;){
                while (a[++i].compareTo(centureValue)<0){ }
                while (a[++j].compareTo(centureValue)>0){ }
                if(i<j){
                    replacePosition(a, i, j);
                }else {
                    break;
                }
            }
            //將中值還原回原來的位置
            replacePosition(a, i,right-1);
            //快速排序較小的哪一組資料
            quickSort(a,left,i-1);
            //快速排序較大的哪一組資料
            quickSort(a, i+1, right);
            
        }else{
            //資料量不大,使用插入排序
            insertSort(a, left, right);
        }
    }

    /**
     * 從陣列中取中值
     * @param a
     * @param left
     * @param right
     * @param <AnyType>
     * @return
     */
    private static <AnyType extends Comparable<? super AnyType>> AnyType media3(AnyType[] a, int left, int right) {
    
        int center = (left+right)/2;
        if(a[center].compareTo(a[left])<0){
            replacePosition(a, left, center);
        }
        if(a[right].compareTo(a[left])<0){
            replacePosition(a,left, right);
        }
        if(a[center].compareTo(a[right])<0){
            replacePosition(a, right ,center);
        }
        //將中值的位置和陣列末尾的位置替換
        replacePosition(a, center, right-1);
        return a[right-1];
    }

    /**
     * 將位置在left的值和位置在center的值交換
     * @param a 陣列
     * @param position1 要交換的位置
     * @param position2 要交換的位置
     */
    private static <AnyType extends Comparable<? super AnyType>> void replacePosition(AnyType[] a, 
                                                                                      int position1, int position2) {
    
        AnyType tmp = a[position1];
        a[position1] = a[position2];
        a[position2] = tmp;
    }

    /**
     * 插入排序
     */
    private static <AnyType extends Comparable<? super AnyType>> void insertSort(AnyType[] a, int left, int right) {
    }
}