什麼是快速排序?
快速排序,顧名思義它排序的速度十分的快。
它快到什麼程度呢?
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
歡迎大家友好交流[握手]