一個例子搞懂快速排序算法

一、快速排序算法

快速排序算法是對冒泡排序的一種改進。
快排基本思想是:通過一趟排序將要排序的數據以基準數據分割成獨立的兩部分,其中一部分的所有數據都比基準數據小,另外一部分的所有數據都比基準數據大,然後再通過遞歸對這兩部分數據分別進行快速排序,實現整個數據變成有序序列。

二、實例排序步驟分析

樣本數據:45 23 68 88 55 12 100 9

  • 基準數: 一般取待排序序列的第一個
  • 目標: 交換後, 基準數左邊的數要全部小於基準數, 其右邊的數要全部大於基準數
    步驟如下:
  • 第一次排序基準數:45
  • 從後往前找到比基準數小的數進行對換,循環找到9小於45,則9和45對換位置,否則右邊下標前移,繼續循環判斷 <-----
    9 23 68 88 55 12 100 45
  • 從前往後找到比基準數大的進行對換,23小於45,左邊下標後移,繼續循環找到68大於45,則68和45對換位置,否則左邊下標後移,繼續循環判斷 ----->
    9 23 45 88 55 12 100 68
  • 從後往前找到比基準數小的數進行對換 <-----
    9 23 12 88 55 45 100 68
  • 從前往後找到比基準數大的進行對換 ----->
    9 23 12 45 55 88 100 68
  • 至此,以基準數分爲3部分,左邊的都比其小,右邊的都比其大,第一次以45爲基準數的排序完成
    {9 23 12} {45} {55 88 100 68}

對於{9 23 12} 和 {55 88 100 68}這兩部分數據再通過遞歸分別進行快速排序。

三、算法實現

實現代碼如下:

/**
 * 快速排序算法
 */
public class QuickSort {
    public static void main(String[] args) {
        int data[] = {45,23,68,88,55,12,100,9};
        quickSort(data, 0, data.length-1);
    }

    private static void quickSort(int[] data, int left, int right){
        int base = data[left];
        int leftIndex = left; // 記錄當前左邊要找的位置
        int rightIndex = right; // 記錄當前右邊要找的位置
        while(leftIndex < rightIndex){
            // 從隊列後面往前找出比base小的第一個數, 沒有滿足條件的則右邊下標前移,繼續判斷
            while(leftIndex < rightIndex && data[rightIndex]>=base){
                rightIndex --;
            }
            // 表示已找到 9
            if (leftIndex < rightIndex){
                swap(data, leftIndex, rightIndex);
                leftIndex ++;
                print(data);
            }
            // 從隊列前面往後找出比base 大的第一個數
            while (leftIndex < rightIndex && data[leftIndex] <= base) {
                leftIndex++;
            }
            // 循環2次後,表示已找到 68
            if(leftIndex < rightIndex){
                swap(data, leftIndex, rightIndex);
                rightIndex --;
                print(data);
            }
        }
        // print(data);
        // 以基準數分爲3部分, 前後部分遞歸排序
        if(leftIndex > left){
            quickSort(data, left, leftIndex-1);
        }

        if(rightIndex < right){
            quickSort(data, leftIndex+1, right);
        }
    }

    /**
     * 對換數據位置
     * @param data
     * @param leftIndex
     * @param rightIndex
     */
    private static void swap(int[] data, int leftIndex, int rightIndex) {
        int temp = data[rightIndex];
        data[rightIndex] = data[leftIndex];
        data[leftIndex] = temp;
    }

    private static void print(int[] data){
        for(int i=0,len = data.length; i<len; i++){
            System.out.print(data[i]+" ");
        }
        System.out.println();
    }

}

運行結果:

9 23 68 88 55 12 100 45 
9 23 45 88 55 12 100 68 
9 23 12 88 55 45 100 68 
9 23 12 45 55 88 100 68 
9 12 23 45 55 88 100 68 
9 12 23 45 55 68 100 88 
9 12 23 45 55 68 88 100 

注: 快速排序的最好的情況(每次數據劃分得很均勻)時間複雜度爲O(nlogn),最壞的情況(需排序的數據爲正序或逆序排列時)複雜度爲O(n^2)。



參考:
圖靈學院趙雲老師-實戰應用Java算法分析與設計公開課

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