Sean's Technology Blog
阿新 • • 發佈:2019-02-19
分治演算法策略:
將原問題劃分成n個規模較小而結構與原問題相似的子問題;遞迴地解決這些子問題,然後再合併其結果,就得到原問題的解。
分治模式步驟:
分解(Divide):將原問題分解成一系列子問題。
解決(Conquer):遞迴地解決各子問題。若子問題足夠小,則直接求解。
合併(Combine):將子問題的結果合併成原問題的解。
合併排序演算法完全依照了上述模式,直觀地操作如下:
分解:將n個元素分成各含n/2個元素的子序列;
解決:用合併排序法對兩個子序列遞迴地排序;
合併:合併兩個已排序的子序列以得到排序結果。
合併排序虛擬碼如下:
MERGE(A, p, q, r) 1 n1 ← q - p + 1 2 n2 ← r - q 3 create arrays L[1 ‥ n1 + 1] and R[1 ‥ n2 + 1] 4 for i ← 1 to n1 5 do L[i] ← A[p + i - 1] 6 for j ← 1 to n2 7 do R[j] ← A[q + j] 8 L[n1 + 1] ← ∞ 9 R[n2 + 1] ← ∞ 10 i ← 1 11 j ← 1 12 for k ← p to r 13 do if L[i] ≤ R[j] 14 then A[k] ← L[i] 15 i ← i + 1 16 else A[k] ← R[j] 17 j ← j + 1
圖示如下:
使用遞迴方法進行排序:
虛擬碼如下:
MERGE-SORT(A, p, r)
1 if p < r
2 then q ← ⌊(p + r)/2⌋
3 MERGE-SORT(A, p, q)
4 MERGE-SORT(A, q + 1, r)
5 MERGE(A, p, q, r)
整個過程可以用下圖來表示:
分治法分析:
分治法的遞迴式可以把原問題分解成a個子問題,每一個的大小是原問題的1/b。如果分解該問題和合並解的時間各為D(n)和C(n),則得到遞迴式:
合併排序演算法的分析:
第一層有一個節點,第二層2各節點,以此類推,第i層有2i 個節點。
由於第i層的節點個數為n,也就是:2i=n, 所以i=lgn。
這個二叉樹的層數為:lg n + 1。
每層得代價都是cn,所以整棵樹的總代價就是:
cn(lg n + 1) = cn lg n + cn
忽略低階項和常量c,即得到結果:
Θ(n lgn).
這就是合併排序的演算法複雜度。