1. 程式人生 > >排序演算法04-快速排序

排序演算法04-快速排序

上一篇文章講述了歸併排序,其實快速排序是基於歸併排序的,二者都是基於分而治之的演算法設計思想,下面講述快速排序與歸併排序的不同之處:

1.歸併排序分割陣列屬於“貨真價實”的分割,建立了兩個新陣列接收分割後的兩個新陣列,而快速排序則通過下標標記來分割,不會建立新陣列;

2.歸併排序分割位置是固定的,每次都是arr.length/2^n(n代表第幾次分割),而快速排序通過樞紐元來分割(樞紐元也是一個數組元素,不過該元素左邊的資料必須小於它,右邊的資料必須大於它);

 

快速排序的難點與重點在於樞紐元的獲取,步驟如下:

1.定義兩個邊界,代表獲取哪一段的樞紐元,假設為i和j,令樞紐元pos=arr[i];

2.從j至i遍歷陣列(即倒序遍歷陣列),直到找到小於pos的元素,賦值arr[i]=arr[j],之後i自增;

3.從i至j遍歷陣列(即正序遍歷陣列),直到找到大於pos的元素,賦值arr[j]=arr[i],之後j自減;

4.將pos賦值給arr[i],返回i,代表調整位置之後樞紐元的位置;

 

如圖:

實現快速排序的簡單程式如下:

    public static void quickSort(int[] arr)
    {
        quickSort(arr, 0, arr.length - 1);
    }

    // 分割槽方法,i為左邊界,j為右邊界
    public static int partition(int[] arr, int i, int j)
    {
        int pos = arr[i];
        while (i < j)
        {
            while (i < j && arr[j] >= pos)
                j--;
            if (i < j)
                arr[i++] = arr[j];
            while (i < j && arr[i] < pos)
                i++;
            if (i < j)
                arr[j--] = arr[i];
        }
        arr[i] = pos;
        return i;
    }

    // 排序方法
    public static void quickSort(int[] arr, int left, int rigth)
    {
        if (left < rigth)
        {
            int pos = partition(arr, left, rigth);
            System.out.println("pos=" + pos);
            // 左邊區塊
            quickSort(arr, left, pos - 1);
            // 右邊區塊
            quickSort(arr, pos + 1, rigth);
        }
    }