排序算法之快速排序詳解(附示例代碼)

1.快速排序簡介
對於包含n個數的輸入數組來說,快速排序是一種最壞情況時間複雜度爲O(n的平方)的排序算法.雖然最壞情況時間複雜度很差,但是快速排序通常是實際排序應用中最好的選擇.因爲他的平均性能非常好,它的期望時間複雜度是O(n lg n),而且其中包含的常數因子非常小.
2.快速排序的原理
快速排序與歸併排序已有,也使用分治思想.下面介紹下對一個典型的子數組A[p..r]進行快速排序的三步分治過程:
分解:數組A[p..r]被劃分爲兩個(可能爲空)子數組A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每一個元素都小於等於A[q],而A[q]也小於等於A[p..q-1]中的每個元素,其中,計算下標q也是劃分過程的一部分.
解決:通過遞歸調用快速排序,對子數組A[p..q-1]和A[q+1..r]進行排序.
合併:因爲子數組都是原址排序的,所以不需要合併操作:數組A[p..r]已經有序.
通俗點講就是把數組根據一個參照值劃分爲兩部分,左邊部分小於等於參照值,右邊部分大於等於參照值,然後再不斷遞歸調用該方法,直到數組只有一個元素,就認爲其是有序的.注意:劃分過程,左邊部分和右邊部分可以是不均衡的.
3.java代碼實現,代碼中關鍵代碼都有註釋

//將數組排序成滿足數組左邊比中間值小,右邊比中間值大的方法
    int partition(int arr[], int left, int right)
    {
        int i = left, j = right;
        int tmp;
        //定義參照值爲數組的中間值
        int pivot = arr[(left + right) / 2];

        while (i <= j) {
            //當arr[i]小於參照值時,符合左邊小的原則,不需調換位置,直接跳過,直到找到不滿足條件的A[i]時終止該循環
            while (arr[i] < pivot)
                i++;
            //當arr[j]大於參照值時,符合右邊大的原則,不需調換位置,直接跳過,直到找到不滿足條件的A[j]時終止該循環
            while (arr[j] > pivot)
                j--;
            //i小於j時,完成a[i]和a[j]的交換
            if (i <= j) {
                tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
                i++;
                j--;
            }
        };
        //返回的i就是滿足i左邊的值比i小.i右邊的值比i大
        return i;
    }

    void quickSort(int arr[], int left, int right) {
        int index = partition(arr, left, right);
//        System.out.println("index"+index);
        if (left < index - 1){
            quickSort(arr, left, index - 1);
//            System.out.println(Arrays.toString(arr));
        }

        if (index < right){
            quickSort(arr, index, right);
//            System.out.println(Arrays.toString(arr));
        }
    }

    @Test
    public void testQuickSort(){
        int a[] = {222,5, 2, 4, 6, 1, 3, 11, 9, 10, 8, 7,0};
        quickSort(a,0,a.length - 1);
        System.out.println("最終排序結果"+Arrays.toString(a));
    }

運行結果如下圖:
運行結果截圖

4.C代碼實現

void quickSort(int arr[], int left, int right) {
      int i = left, j = right;
      int tmp;
      int pivot = arr[(left + right) / 2];

      /* partition */
      while (i <= j) {
            while (arr[i] < pivot)
                  i++;
            while (arr[j] > pivot)
                  j--;
            if (i <= j) {
                  tmp = arr[i];
                  arr[i] = arr[j];
                  arr[j] = tmp;
                  i++;
                  j--;
            }
      };

      /* recursion */
      if (left < j)
            quickSort(arr, left, j);
      if (i < right)
            quickSort(arr, i, right);
}

5.快速排序的性能分析.
a.最壞情況分析
在最壞情況下,快速排序每一層遞歸的時間複雜度是n的平方.
特例:當劃分非平衡的時候,快速排序的運行時間爲n的平方
b.期望運行時間
在輸入元素互異的情況下,快速排序算法的期望運行時間爲n lg n.
如有疑問請直接在評論提出
不足之處請指正,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章