用Python實現快速排序(Quicksort)演算法
阿新 • • 發佈:2019-01-29
1.快速排序(Quicksort)演算法介紹
快速排序(Quicksort)是對氣泡排序的一種改進,但是不是穩定的排序演算法
2.演算法思想
1)設定兩個變數i、j,排序開始的時候:i=0,j=N-1; 2)以第一個陣列元素作為關鍵資料,儲存在key中,即key=A[0]; 3)從j開始向前搜尋,即由後開始向前搜尋(j--),找到第一個小於key的值A[j],用A[j]覆蓋A[0], 4)從i開始向後搜尋,即由前開始向後搜尋(i++),找到第一個大於key的A[i],用A[i]覆蓋A[j] 即每一次覆蓋上一次的 5)重複第3、4步,直到i=j;找到符合條件的值,進行交換的時候i, j指標位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令迴圈結束。 6) 將K還原 7) 第一遍快速排序不會直接得到最終結果,只會把比k大和比k小的數分到k的兩邊。為了得到最後結果,需要再次對下標2兩邊的陣列分別執行此步驟,然後再分解陣列,直到陣列不能再分解為止(只有一個數據),才能得到正確結果。
3. 第一趟排序 舉例如下
key = 3 i--> <--j 3 7 6 2 4 5 j走 i--> <--j 2 7 6 2 4 5 i走 i--> <--j 2 7 6 7 4 5 j走 i--><--j 2 3 6 7 4 5 i走 第一趟排序走完,key(key = 3)左邊的值都比3小,key右邊的值都比key大
4.用Python3實現
方法1
def quick_sort(list, low, high): """ 控制快速排序遞迴的主函式 :param list:使用者傳入的待排序列表 :param low:列表左下標 :param high:列表右下標 """ if low < high: k_index = deal_list(list, low, high) # 遞迴分界值左邊的一組 quick_sort(list, low, k_index - 1) # 遞迴分界值右邊的一組 quick_sort(list, k_index + 1, high) def deal_list(list, low, high): """實現每趟排序,並找出分界值的下標k_index""" # 必須把low ,high儲存起來,上面的主函式的left right始終不變 left = low right = high # 將列表最左邊的值賦值給k k = list[low] while left < right: # 當左右"指標"未碰頭時就一直比較移動下去 # 從右邊開始,如果比K大:right左移一位,繼續比較 while list[right] > k: right -= 1 # 從左邊開始,如果比K小: left右移一位,繼續比較 while list[left] <= k: left += 1 # 若移動完,二者仍未相遇則交換下標對應的值 if left < right: list[right], list[left] = list[left], list[right] # 若移動完,已經相遇,則交換right對應的值和k list[low] = list[right] list[right] = k return right if __name__ == '__main__': list = [6, 1, 2, 7, 9, 3, 4, 5, 10, 8] quick_sort(list, 0, len(list) - 1) print(list)
方法2
import time, random
def quick_sort(list, low, high):
# 1)
# 必須將low high儲存,因為下面的遞迴 還要固定著 最邊界
i = low
j = high
if i >= j:
return list
key = list[i] # 2)
while i < j:
# 3)
while i < j and list[j] >= key:
j = j - 1
list[i] = list[j]
# 4)
while i < j and list[i] <= key:
i = i + 1
list[j] = list[i]
# 6)
list[i] = key
# 7)
quick_sort(list, low, i - 1)
quick_sort(list, j + 1, high)
return list
if __name__ == '__main__':
list = [random.randint(1, 100) for i in range(100)]
start_time = time.time()
quick_sort(list, 0, len(list) - 1)
# list = sorted(list)
end_time = time.time()
print("所用時間:", end_time - start_time)
5.結果如下
7.時間複雜度 空間複雜度分析
在最優的情況下,快速排序演算法的時間複雜度為O(nlogn)。 平均的情況 O(nlogn)。 就空間複雜度來說,主要是遞迴造成的棧空間的使用,最好情況,遞迴樹的深度為log2n,其空間複雜度也就為O(logn),最壞情況,需要進行n‐1遞迴呼叫,其空間複雜度為O(n),平均情況,空間複雜度也為O(logn)。
如果你和我有共同愛好,我們可以加個好友一起交流!