排序算法系列——快速排序

什麼是快速排序?

快速排序,顧名思義它排序的速度十分的快。

它快到什麼程度呢?

C語言標準庫中的qsort函數就是使用快速排序實現的!

說到快速排序,離不開兩個重要的概念: 遞歸分治算法(Divide ans conquer, D&C)

如果要講清楚這兩個概念,可以單獨寫兩篇文章出來了。

因此這裏不做深入,只簡單介紹一下:

遞歸:重複調用自己的函數。一般由兩個部分組成基線條件遞歸條件,程序在符合基線條件的時候返回,在符合遞歸條件的時候調用自己。

分治算法(Divide ans conquer, D&C): 將大的問題化解爲相同類型的小問題。一種著名的遞歸式問題解決辦法,一般分爲兩個步驟,首先找出儘可能簡單的基線條件,然後將遞歸的將問題分解爲小問題,直到小問題符合基線條件

假如還不太明白這兩個概念,沒關係,看下面的例子就可以了。

排序過程

既然快速排序的核心思想是D&C,那麼它的基線條件遞歸條件分別是什麼呢?

首先我們思考一下,什麼樣的數組需要排序

長度爲0的數組需要排序嗎?
不需要。因爲它的沒有順序的概念。

長度爲1的數組需要排序嗎?
不需要。因爲可以把它看做一個有序數組了。

長度爲2的數組需要排序嗎?
需要。因爲並不能確定它的順序。

因此,我們可以把長度爲0或1的數組設爲是基線條件
遞歸條件則是長度大於1的數組

舉個例子:

假如現在有一個無序數組disorder_arr = [4,2,19,10,-1]

第一步:
我們取第一個數4基準數

然後將小於4的分成一類:[2,-1],放在4的左邊

大於4的分成一類:[19,10],放在4的右邊。

第二步:
長度大於1 的數組重複上面的步驟,如下圖所示:

圖片

直到所有的數組都符合基線條件(長度爲0或1)後,
我們便可得到一個排列有序的數組了。

寫一段代碼

代碼依然是使用Python3實現的

# quickSort.py
class Solution:
    def quick(self, disorder_arr: list):
        # 遞歸實現
        if len(disorder_arr) < 2: # 基線條件
            return disorder_arr

        base_num = disorder_arr[0] # 基數,取數組第一個數
        min_arr = [] # 小於基數的數
        max_arr = [] # 大於基數的數
        for i in range(1, len(disorder_arr)): # 遍歷一遍數組,
            if disorder_arr[i] <= base_num:
                min_arr.append(disorder_arr[i])
            elif disorder_arr[i] > base_num:
                max_arr.append(disorder_arr[i])

        return self.quick(min_arr) + [base_num] + self.quick(max_arr) # 遞歸

總結

快速排序的原理是首先找到一個基準數,然後通過遍歷數組,
小於基準數的數分成一類,放在基準數的左邊,
大於基準數的數分成另一類,放在基準數的右邊。

在最優情況下,快速排序算法的平均時間複雜度是O(nlogn),
但是最壞的情況下,它的時間複雜度也會達到O(n^2)

以上代碼已上傳至github

歡迎大家友好交流[握手]

發佈了15 篇原創文章 · 獲贊 4 · 訪問量 8999
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章