歸併排序python實現
- 2020 年 1 月 16 日
- 筆記
歸併排序python實現
歸併排序
歸併排序在於把序列拆分再合併起來,使用分治法來實現,這就意味這要構造遞歸演算法
首先是一個例子

原序先通過一半一半的拆分,然後:

然後再一步一步的向上合併,在合併的過程中完成了排序,合併排序演算法如下:
def merge(s1,s2,s): """將兩個列表是s1,s2按順序融合為一個列表s,s為原列表""" # j和i就相當於兩個指向的位置,i指s1,j指s2 i = j = 0 while i+j<len(s): # j==len(s2)時說明s2走完了,或者s1沒走完並且s1中該位置是最小的 if j==len(s2) or (i<len(s1) and s1[i]<s2[j]): s[i+j] = s1[i] i += 1 else: s[i+j] = s2[j] j += 1
這是以列表為例,道理其實很簡單,因為兩個序列是排好序的,所以都從左往右,互相比較選擇較小的那個數放入最後的序列,s是原序列,所以在一開始會有與len(s)的比較
完整演算法
演算法中通過遞歸併調用merge函數完成排序
def merge(s1,s2,s): """將兩個列表是s1,s2按順序融合為一個列表s,s為原列表""" # j和i就相當於兩個指向的位置,i指s1,j指s2 i = j = 0 while i+j<len(s): # j==len(s2)時說明s2走完了,或者s1沒走完並且s1中該位置是最小的 if j==len(s2) or (i<len(s1) and s1[i]<s2[j]): s[i+j] = s1[i] i += 1 else: s[i+j] = s2[j] j += 1 def merge_sort(s): """歸併排序""" n = len(s) # 剩一個或沒有直接返回,不用排序 if n < 2: return # 拆分 mid = n // 2 s1 = s[0:mid] s2 = s[mid:n] # 子序列遞歸調用排序 merge_sort(s1) merge_sort(s2) # 合併 merge(s1,s2,s) if __name__ == '__main__': s = [1,7,3,5,4] merge_sort(s) print(s)
時間複雜度
還拿這個圖說

這個圖顯然是二叉樹的形式,所以若集合有n個元素,那高度就為log(n)
但其實在每一層做比較的時候,都是一個一個的向序列中放小的元素,每一層都是要放n次
所以時間複雜度為nlog(n)