分治算法策略:
将原问题划分成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).
这就是合并排序的算法复杂度。