數組排序-快速排序(Quick Sort)



概念:

    快速排序是對冒泡排序的一種改進。由C.A.R.Hoare於1962年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。


排序過程:

    假設要排序的數組是A[0]..A[N-1],首先任意選取一個數據(通常選用數組的第一個數)作為關鍵數據,然后將所有比它小的數都放到它的前面,所有比它大的數據都放到它的后面,這個過程稱為一趟快速排序。值得注意的是:快速排序不是一種穩定的排序算法,也就是說,多個相同的值的相對位置也許會在算法結束時產生變動。
    一趟快速排序的算法是:
    1.設置兩個變量i、j,排序開始時:i=0; j=N-1;
    2.以第一個數組元素作為關鍵數據,賦值給key,即key=A[0];
    3.從j開始向前檢索,即由后向前開始檢索(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;
    4.從i開始向后檢索,即由前向后開始檢索(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;
    5.重復第3、4步,直到i=j;(3、4步中,沒找到符合條件的值,即第3步中A[j]不小於key,第4步中A[i]不大於key時改變i、j的值,使得j=j-1; i=i+1; 直至找到該值為止。找到符合條件的值,進行交換的時候i和j的指針位置不變。另外,i==j這一過程一定正好是i++或j--完成的時候,此時令循環結束)


示例:

package com.cnblogs.lxj.testarraysort;

/**
 * @author liuxiaojiang
 * @packageName:com.cnblogs.lxj.testarraysort
 * @ClassName:QuickSort
 * @Description:測試快速排序
 * @date 2020/11/30
 */
public class QuickSort {

    /**
     * 主方法
     * @param args
     */
    public static void main(String[] args) {
        int[] a = {5,1,9,3,7,4,8,6,2};
        printArray(a);
        quickSort(0,a.length - 1,a);
        printArray(a);
    }

    /**
     * 快速排序方法
     * @param low
     * @param high
     * @param a
     */
    public static void quickSort(int low,int high,int[] a){
        if(low < high){
            int middle = getMiddle(low,high,a);
            quickSort(low,middle - 1,a);
            quickSort(middle + 1,high,a);
        }
    }

    /**
     * 邏輯算法
     * @param low
     * @param high
     * @param a
     * @return
     */
    public static int getMiddle(int low,int high,int[] a){
        int temp = a[low];
        while(low < high){
            while(a[high] >= temp && low < high){
                high--;
            }
            a[low] = a[high];
            low++;
            while(a[low] <= temp && low < high){
                low++;
            }
            a[high] = a[low];
        }
        a[high] = temp;
        return high;
    }

    /**
     * 輸出方法
     * @param array
     */
    public static void printArray(int[] array){
        for(int a : array){
            System.out.print(a + " ");
        }
        System.out.println();
    }
    
}

運行結果:

5 1 9 3 7 4 8 6 2      //初始化
1 2 3 4 5 6 7 8 9      //快速排序完成

原理:


算法分析:

    快速排序可以說是數組排序中性能最好的排序算法,但它是不穩定的算法,比如當同一數組中有兩個(或多個)值相同的元素時,排序完成后,該多個元素位置(順序)可能會發生改變。快速排序主要有兩個基本操作:一是選取樞軸元素,另一個則是遞歸分割數組。樞軸元素的選取對快速排序的效率至關重要,因為它決定了遞歸的深度。如果樞軸元素剛好處於數組的中間值,那么,數組在分割時就分成了平均的兩部分。這樣的遞歸的效率就好。如果每次選取的樞軸元素都是最大/最小 的那個元素,則快排復雜度達到了O(N2),而且還用了遞歸棧空間。快速排序的時間復雜度與樞軸元素的選取息息相關。平均情況下,時間復雜度為O(NlogN),最壞情況下為O(N2)。所以,快速排序更適合數據量比較大時使用。(另:需要注意,當選取數組元素中的最小值作為樞軸且要降序時,這時候的執行時間巨長,所以,在使用時需要根據實際情況調整)



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM