懵X排序算法:快速排序

原文地址:xeblog.cn/articles/17數組

快速排序基本思想

快速排序使用的是 分治思想,經過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據都比另一部分的全部數據都要小,而後再按此方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列。bash

實現思路

  • 設置一個基準值 k ,通常取數組第一個元素,以此值分割數組;
  • 設置兩個掃描員,分別爲 iji 指向數組的最低位j 指向數組的最高位
  • 首先由 j 開始從數組最高位往數組最低位(j--)掃描比 k 小的值,掃描到後中止掃描,並將該值填入 i 所處的位置,而後再由 i 開始從數組最低位 往數組最高位(i++)掃描比 k 大的值,掃描到後中止掃描,並將該值填入 j 所處的位置,ji 依次掃描,直至 ji 的位置相互重合後,將 k 的值填入重合處,此時,數組左側的值均小於 k,右側值均大於 k,完成這次排序;
  • 分別對數組左右兩邊的值作如上操做後便可完成快速排序。

演示圖 測試

快速排序演示圖.gif

代碼實現

/** * 快速排序 * @param array 待排序數組 * @param begin 起點索引 * @param end 終點索引 */
    private static void fastSort(int[] array, int begin, int end) {
        // 遞歸終止條件,起點索引大於等於終點索引
        if (begin >= end) {
            return;
        }

        // 起點索引
        int i = begin;
        // 終點索引
        int j = end;
        // 基準值
        int k = array[begin];

        // 循環條件:起點索引小於終點索引
        while (i < j) {
            /* 這個循環是要掃描小於基準值的值,掃描到後退出循環, 循環條件:當前索引位的值大於等於基準值k(加等於號是防止相同數字交換而陷入死循環中), 且起點索引小於終點索引(防止數組下標出界) */
            while (array[j] >= k && i < j) {
                // 終點索引位從右至左逐個遞減
                j--;
            }

            if (i < j) {
                // 將小於基準值的數移至左側
                array[i] = array[j];
            }

            /* 這個循環是要掃描大於基準值的值,掃描到後退出循環, 循環條件:當前索引位的值小於等於基準值k(加等於號是防止相同數字交換而陷入死循環中), 且起點索引小於終點索引(防止數組下標出界) */
            while (array[i] <= k && i < j) {
                // 起點索引位從左至右逐個遞增
                i++;
            }
            if (i < j) {
                // 將大於基準值的數移至右側
                array[j] = array[i];
            }
        }
        if (array[j] != k) {
            // 基準值歸位(數組的中間某個位置),歸位後,基準值左側都是小於基準值的數,右側都是大於基準值的數
            array[j] = k;
        }
        // 遞歸將基準值左側的數排序
        fastSort(array, begin, j - 1);
        // 遞歸將基準值右側的數排序
        fastSort(array, j + 1, end);
    }
複製代碼

測試排序spa

int[] array = {5, 6, 6, 4, 3, 5, 5};
System.out.println("排序前:" + Arrays.toString(array));
fastSort(array, 0, array.length - 1);
System.out.println("排序後:" + Arrays.toString(array));
複製代碼

輸出結果code

排序前:[5, 6, 6, 4, 3, 5, 5]
排序後:[3, 4, 5, 5, 5, 6, 6]
複製代碼

快速排序的時間複雜度

平均時間複雜度: O(nlogn)
最壞時間複雜度: O(n^2) ,這種狀況發生在排序數組爲正序逆序的時候。
穩定性: 不穩定。cdn

相關文章
相關標籤/搜索