Python 實現快排


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

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

特點:
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、快速排序實踐步驟:
划分組:准備工作+左右移動+元素歸位
遞歸:函數自調用+退出條件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM