许多有用的算法在结构上是递归的:为了解决一个给定的问题,算法一次或多次的调用自身以解决紧密相关的若干子问题。
这些递归算法遵循分治法的思想:将原问题分解成若干个和原问题相似的子问题,然后递归的求解子问题,最后把子问题的解合并,就为最终原问题的解。
分治模式在每层递归时都有3个步骤:
- 分解成子问题
- 解决子问题
- 合并子问题的解
接下来看一下归并排序:归并排序严格遵守分治思想
1. 把长度为n的数组分解成n/2的子数组
2. 使用归并排序递归求解出两个子序列
3. 合并两个已经排好序的子序列
假设我们已经有一个算法MERGE(A,p,q,r)来完成合并,A表示一个数组,P,q,r表示数的下标,MERGE(A,p,q,r)是用来合并两个已经排好序的数组A[p,q]和A[q+1,r],具体实现现在先不管
那么归并排序算法:
MERGESORT(A,p,r)
q=(p+r)/2
MERGESORT(A,p,q)
MERGESORT(A,q+1,r)
MERGE(A,p,q,r)
分治法时间复杂度分析:
1. 当规模很小时,
T(n)=θ(1)
2. 假设规模为n 时,时间复杂度为
T(n)
3. 分解成a个子问题,每个子问题为n/b,花费时间为:
D(n)
4. 解决每个子问题花费时间为:
T(n/b)
5. 合并子问题的解花费时间为:
C(n)
6. 综上,
T(n)=T(n/b)+C(n)+D(n)
分析归并排序的时间复杂度:
1. 当排序一个元素时需要
θ(1)
的时间
2. 分解需要
θ(1)
的时间
3. 解决n/2的子问题需要T(n/2)的时间
4. 合并需要
θ(n)
的时间
5. 综上:
T(n)=T(n/2)+θ(n)
T(n)=θ(nlgn)