1. 程式人生 > 實用技巧 >排序演算法—快速排序(Quick Sort)

排序演算法—快速排序(Quick Sort)

快速排序(Quick Sort)

快速排序的基本思想:通過一趟排序將待排記錄分隔成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。

1.演算法描述

快速排序使用分治法來把一個串(list)分為兩個子串(sub-lists)。具體演算法描述如下:

  • 從數列中挑出一個元素,稱為 “基準”(pivot);
  • 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割槽退出之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作;
  • 遞迴地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。/

2.具體演算法實現

  • 先選擇一個基準(base),一般是陣列最左邊的值,或者是最右邊的值(如果base是左邊,則從右邊開始。)

  • 如果j需要從右往左遍歷,如果發現arr[j]<base則停下,i開始從左往右遍歷,發現arr[i]>base停下。
  • 交換arr[i]與arr[j]的位置
  • 然後j和i繼續尋找,並交換位置

  • 當i和j相同時,結束一輪尋找,並將此時的數字與base交換。
  • 此時根據base,將陣列分割成兩個部分,其中一部分記錄的關鍵字均比另一部分的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。

3. 演算法分析

快速排序演算法的時間複雜度和各次標準資料元素的值關係很大。如果每次選取的標準元素都能均分兩個子陣列的長度,這樣的快速排序過程是一個完全二叉樹結構。(即每個結點都把當前陣列分成兩個大小相等的陣列結點,n個元素陣列的根結點的分解次數就構成一棵完全二叉樹)。這時分解次數等於完全二叉樹的深度log2n;每次快速排序過程無論把陣列怎樣劃分、全部的比較次數都接近於n-1次,所以最好情況下快速排序演算法的時間複雜度為O(nlog2n):快速排序演算法的最壞情況是資料元素已全部有序,此時資料元素陣列的根結點的分需次數構成一棵二叉退化樹(即單分支二叉樹),一棵二叉退化樹的深度是n,所以最壞情況下快速排序演算法的時間複雜度為O(n2)。般情況下 ,標準元素值的分佈是隨機的,陣列的分郵大數構成模二又樹,這樣的二叉樹的深度接近於log2n, 所以快速排序演算法的平均(或稱期望)時間複雜度為O(nlog2n)

public class quickSort {
    public static  void  main(String[] args)
    {
        int[] arr=new int[10000];
        int n=arr.length;
        Random random = new Random();//預設構造方法
        for(int i=0;i<n;i++)
        {
            arr[i]=(int)random.nextInt(100);//在陣列中隨機生成[0,100)的數
        }
        funQuickSort(arr,0,n-1);

    }

    public static  void funQuickSort(int[] arr,int start,int end )
    {
        if(start>end)
        {
            return;
        }
        int base=arr[start];
        int i=start;
        int j=end;
        while (i!=j)
        {
            while(arr[j] >= base && i < j)
            {
                j--;
            }
            while(arr[i] <= base && i < j)
            {
                i++;
            }
            int temp=arr[i];
            arr[i]=arr[j];
            arr[j]=temp;
        }
        arr[start]=arr[i];
        arr[i]=base;
        funQuickSort(arr,start,i-1);
        funQuickSort(arr,j+1,end);
    }
}

快速排序前的陣列:2 43 7 46 43 25 26 36 22 35 32 41 26 34 42 29 39 43 4 3 46 4 17 45 36 48 21 16 26 0 39 45
快速排序後的陣列:0 2 3 4 4 7 16 17 21 22 25 26 26 26 29 32 34 35 36 36 39 39 41 42 43 43 43 45 45 46 46 48