1. 程式人生 > >Python 實現快排

Python 實現快排

位置 div 時間復雜度 部分 blog ont 退出 分數 pan

快速排序簡介
快速排序,又稱劃分交換排序,從無序隊列中挑取一個元素,把無序隊列分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
簡單來說:挑元素、劃分組、分組重復前兩步

快速排序原理示意圖
通過上面對快速排序的簡介,我們知道了,快速排序主要包括以下兩方面:
挑元素劃分組、整體遞歸分組
挑元素劃分組示意圖:

技術分享圖片

特點:
1、因為是無序隊列,所以位置可以隨機挑
2、臨時劃分一個空間,存放我們挑選出來的中間元素
3、左標簽位置空,移動右標簽,反之一樣
4、重復3,直到左右側標簽指向同一個位置,
5、把臨時存放的中間元素,歸位
一句話:左手右手一個慢動作,右手左手慢動作重播

整體劃分示意圖:

技術分享圖片

特點:
1、遞歸拆分
2、拆分到最後,所有小組內的元素個數都是1
一句話:遞歸拆分到不能再拆

代碼實踐分析
根據上面兩個示意圖的分析,我們要從兩個大方面分析:
序列切割 和 遞歸拆分

1、序列切割
序列切割這個知識點,我們從四個方面分別介紹:
3個基本標簽、右側推進、左側推進、停止推進(即元素歸位)

1.1、3個基本標簽
大小區域切割,至少涉及到三個標簽:
mid:指定要切割的臨時中間數字
left:從隊列左側推進的標簽
right:從隊列右側推進的標簽 技術分享圖片

 1 def quick_sort(li, start, end):
2 # 分治 一分為二 3 # start=end ,證明要處理的數據只有一個 4 # start>end ,證明右邊沒有數據 5 if start >= end: 6 return 7 # 定義兩個遊標,分別指向0和末尾位置 8 left = start 9 right = end 10 # 把0位置的數據,認為是中間值 11 mid = li[left] 12 while left < right: 13 # 讓右邊遊標往左移動,目的是找到小於mid的值,放到left遊標位置
14 while left < right and li[right] >= mid: 15 right -= 1 16 li[left] = li[right] 17 # 讓左邊遊標往右移動,目的是找到大於mid的值,放到right遊標位置 18 while left < right and li[left] < mid: 19 left += 1 20 li[right] = li[left] 21 # while結束後,把mid放到中間位置,left=right 22 li[left] = mid 23 # 遞歸處理左邊的數據 24 quick_sort(li, start, left-1) 25 # 遞歸處理右邊的數據 26 quick_sort(li, left+1, end) 27 28 if __name__ == __main__: 29 l = [6,5,4,3,2,1] 30 # l = 3 [2,1,5,6,5,4] 31 # [2, 1, 5, 6, 5, 4] 32 quick_sort(l,0,len(l)-1) 33 print(l) 34 # 穩定性:不穩定 35 # 最優時間復雜度:O(nlogn) 36 # 最壞時間復雜度:O(n^2)

關鍵點:
序列切割:
1、挑中間元素:mid = alist[start]
2、右推進:while right > left and alist[right] >= mid:
3、左推進:while left < right and alist[left] < mid:
4、推進循環:while left < right:
5、元素歸位:alist[left] = mid
遞歸拆分:
1、小組邊界確定:left = start、right = end
2、遞歸退出條件:if start < end:
3、函數自調用:quick_sort(alist, start, end)

時間復雜度
最優時間復雜度:O(nlogn)
對於每次快排,left和right的標簽分別在左右兩冊數據全部都移動了一遍,相當於遍歷了所有數據,那麽時間復雜度是O(n)
因為涉及到了遞歸分組,所以他的時間復雜度是O(logn)
整體來說:最優的時間復雜度是 O(nlogn)

最壞時間復雜度:O(n2)

技術分享圖片

因為遞歸分組分組的條件不一定是二分,有可能每一次mid指定的都是最大或者最小,那麽有多少個元素,我們就可能分多少次組,這種情況時間復雜度就是O(n)了
所以最壞的時間復雜度就是O(n2),那麽最壞也不過如此了。
穩定性:不穩定

技術分享圖片

思考:
改哪個地方,結果是降序?
while right > left and alist[right] >= mid: 代碼中的 >= 改為 <=
while left < right and alist[left] < mid 代碼中的 < 改為 >
本節內容小結:
1、快速排序原理:挑元素、劃分組,分組重復前兩步。
2、快速排序實踐步驟:
劃分組:準備工作+左右移動+元素歸位
遞歸:函數自調用+退出條件

Python 實現快排