在路上---學習篇(一)Python 數據結構和算法 (4) --希爾排序、歸並排序
阿新 • • 發佈:2017-11-25
改進 randint 循環 打印 中一 隨機 關鍵詞 shel 條件
獨白:
希爾排序是經過優化的插入排序算法,之前所學的排序在空間上都是使用列表本身。而歸並排序是利用增加新的空間,來換取時間復雜度的減少。這倆者理念完全不一樣,註定造成的所消耗的時間不同以及空間上的不同。
歸並排序涉及到遞歸的使用,需要理解其中精髓才能更好了解歸並排序,以及其他應用到遞歸的算法。理解其本質才能更好的應用。
希爾排序
希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進版本。希爾排序是非穩定排序算法。該方法因DL.Shell於1959年提出而得名。 希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。
時間復雜度
- 最優時間復雜度:根據步長序列的不同而不同
- 最壞時間復雜度:O(n2)
- 穩定想:不穩定
""" 希爾排序 最優時間復雜度: 根據步長序列不同而不同 最壞時間復雜度: O(n*n) 穩定性 : 不穩定 """ import time import random def shell_sort(list): n = len(list) #初始步長 gap = n // 2 while gap > 0: # 按初始步長進行插入排序 for j in range(gap, n): i = j# 插入排序 while i >= gap and list[i-gap] > list[i]: list[i-gap], list[i] = list[i], list[i-gap] i -= gap # 得到新的步長 gap = gap // 2 def new_num(lis): """隨機生成50個數加入列表中""" for i in range(50): j = random.randint(0, 10000) lis.append(j)if __name__ == ‘__main__‘: first_time = time.time() # 空列表 lis = [54,26,93,17,77,31] # 隨機函數添加到列表中 # new_num(lis) print(lis) # 列表排序 shell_sort(lis) print(lis) # 結束時間 last_time = time.time() print("共用時%s" % (last_time - first_time))
歸並排序
歸並排序是采用分治法的一個非常典型的應用。歸並排序的思想就是先遞歸分解數組,再合並數組。
將數組分解最小之後,然後合並兩個有序數組,基本思路是比較兩個數組的最前面的數,誰小就先取誰,取了後相應的指針就往後移一位。然後再比較,直至一個數組為空,最後把另一個數組的剩余部分復制過來即可。
時間復雜度
- 最優時間復雜度:O(nlogn)
- 最壞時間復雜度:O(nlogn)
- 穩定性:穩定
""" 歸並排序 最優時間復雜度:O(nlogn) 最壞時間復雜度:O(nlogn) 穩定性:穩定 與其他排序區別 利用一個新列表講算法排序後的元素儲存當中 空間換時間 """ import time import random def merge_sort(list): """歸並排序""" n = len(list) if n <= 1: return list # 最大整除 mid = n // 2 # left 利用遞歸 截取的列表形成的有序列表 left_list = merge_sort(list[:mid]) # right 利用遞歸 截取的列表形成的有序列表 right_list =merge_sort(list[mid:]) # 創建 左右遊標記錄列表值的索引 left_pointer, right_pointer = 0,0 # 創建新空列表 result = [] # 循環 比較數值大小 # 退出循環條件 當左右遊標其中一個等於所在列表的長度時 while left_pointer < len(left_list) and right_pointer < len(right_list): # 判斷 左值和右值大小 if left_list[left_pointer] <= right_list[right_pointer]: result.append(left_list[left_pointer]) # 每判斷一次 遊標加一 left_pointer += 1 else: result.append(right_list[right_pointer]) right_pointer += 1 # 將最後一個數值加入新列表中 result += left_list[left_pointer:] result += right_list[right_pointer:] # 返回值 return result def new_num(lis): """隨機生成50個數加入列表中""" for i in range(50): j = random.randint(0, 100) lis.append(j) if __name__ == ‘__main__‘: first_time = time.time() # 空列表 lis = [] # 隨機函數添加到列表中 new_num(lis) print(lis) # 列表排序 # 因為歸並排序最後是返回一個新列表,所以打印輸出為新列表 alist = merge_sort(lis) print(alist) # 結束時間 last_time = time.time() print("共用時%s" % (last_time - first_time))
在路上---學習篇(一)Python 數據結構和算法 (4) --希爾排序、歸並排序