資料結構之內部排序--快速排序
阿新 • • 發佈:2018-11-13
概要
-IDE:Pycharm
-Python版本:python3.x
-演算法分類:內部排序->交換類排序->快速排序
演算法思想
待排序記錄序列中選取一個記錄為樞軸,其關鍵字為$k_1$,然後將其餘關鍵字小於$k_1$的移到前面,大於$k_1$的移到後面,結果是待排序記錄分為兩個子表,最後將關鍵字$k_1$插到中間處。這個過程稱為一趟快速排序。對分割後的序列,按上述規則繼續劃分直到所有子表長度不大於$1$,此時待排序記錄成為一個有序表。
演算法分析
分析快速排序的時間耗費,共需要進行多少趟排序,取決於遞迴深度。
1.快速排序的最好情況是每一趟排序都將序列一分為二,正好在表中間,將表分為大小相等的子表,類似於折半查詢,其時間複雜度約為$O(nlog_{2^n})$
2.快速排序的最壞情況是已經排好序,第一趟經過$n-1$次比較,第一個記錄停在原地,產生的左邊的列表長度為$0$,右邊的列表長度為$n-1$,這樣下來比較的次數為$\sum_{i=1}^{n-1}(n-i)=(n-1)+(n-2)+...+1=\frac{n(n-1)}{2}\approx \frac{n^2}{2}$
快速排序所需的時間平均值為$T_{avg}(n)=Knlog_{2^n}$,其中K為某個常數。
3.快速排序遞迴演算法的執行過程對應一顆而叉樹,理想狀態下是一顆完全二叉樹,遞迴工作站的大小,與此二叉樹的深度對應,平均情況下空間複雜度為$O(log_{2^n})$。
穩定性與時間複雜度
排序演算法 | 穩定性 | 時間複雜度 | 最好情況 | 最壞情況 | 空間複雜度 |
---|---|---|---|---|---|
快速排序 | 不穩定 | $O(nlog_{2^n})$ | $O(nlog_{2^n})$ | $O(n^2)$ | $O(log_{2^n})$ |
Python程式碼清單
# !/usr/bin/python3 # _*_ coding:utf-8 _*_ # 快速排序 import sys, random, time # 匯入包 def make_numbers(number, maxNumber): # 用於生成列表的演算法。 listA = [] for i in range(number): listA.append(random.randint(0, maxNumber)) print(listA) return listA # 返回列表 def quick_sort(listA, low, high): # 進行快速排序的演算法。 global pos # 設定全域性變數,因為我這裡是把一次排序的演算法寫到另一個方法裡的。 if low < high: # 判斷是否相交。 pos = quick_pass(listA, low, high) # 一次排序。 quick_sort(listA, low, pos-1) # 左子樹。遞迴呼叫。 quick_sort(listA, pos+1, high) # 右子數。 return listA # 返回排好的list def quick_pass(listA, low, high): # 一次快速排序演算法。 pivot = listA[low] # 記錄低點的值 while low < high: # 判斷是否相交 while low < high and listA[high] >= pivot: # 在沒有相交的情況下,從右向左尋找大於低點的值的數。 high = high-1 # 高位減一。向前走一位。 if low < high: # 如果高低位沒有相交, listA[low] = listA[high] # 沒啥意思。就是給個值。 low = low + 1 # 低位向前1位。 while low < high and listA[low] < pivot: # 同理,尋找小於低點的值。 low = low + 1 if low < high: listA[high] = listA[low] high = high - 1 listA[low] = pivot # 最後,將低點的值放到low點,或者high點。(此地low = high) return low if __name__ == '__main__': helpInfo = ''' This program is for Quick Sort. How to use it! Follow the example! python Quick_Sort.py 10 100 The 10 representative will generate ten numbers. 100 representative the max-number you make. ''' command = sys.argv[0:] # 從鍵盤獲取輸入。 if len(command) != 3 or 'help' in command: # 對輸入的引數進行檢查。 print(helpInfo) # 列印幫助文字 else: try: # 嘗試將輸入測引數轉化為int型。 number = int(command[1]) maxNumber = int(command[2]) except ValueError: # 轉化失敗,出現ValueError print(helpInfo) # 列印幫助文字。 sys.exit(1) # 異常退出 listA = make_numbers(number, maxNumber) # 一切正常, 生成列表listA。 timeStart = time.time() # 記錄開始時間 list = quick_sort(listA, 0, number-1) # 接收返回的排序好的list timeEnd = time.time() # 記錄結束時間。 timeIs = timeEnd - timeStart # 記錄消耗時間。 print('排序%d個數花費的時間是%f' % (number, timeIs)) # 輸出訊息資訊。 print(list)
有什麼問題請聯絡我
QQ:3116316431 (請附上資訊)
E-mail:[email protected]