一、分治法
对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,
否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地
解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。
二、一般步骤:
1. 划分步骤:在算法的这个步骤中,把输入的问题实例划分为k≥1 个子问题,每个实例的规模严格小于问题的原始规模n。一般来说,应尽量将k 个子问题的规模大致相同。k=2 是最通常的情况,有时也有k=1 的划分。
2. 治理步骤:当子问题的规模大于某个预定的阈值时,这个步骤是由k个递归调用组成的;如果子问题的规模小于阈值时则直接对问题进行求解。
3. 组合步骤:这个步骤是组合k 个子问题的解来得到期望的原问题的解。组合步骤对分治算法的性能起到非常关键的影响,算法的效率在很大程度上依赖于组合步骤地实现。
三、时间估计
四、例子
4.1、寻找具有n 个元素的数组a[0, n-1]中的最大与最小元素
种解决这个问题的方法是使用分治法:可以把数组a 分成大小相等的两个数组a1 和a2,在a1 和a2 中分别找出最大和最小元素,然后比较a1 和a2 中的最大和最小元素,两个最大元素中大的就是原数组中的最大元素,两个最小元素中小的就是原数组中的最小元素。为了要在a1 和a2 中找到最大与最小元素,可以重复上述过程,分别将a1 分为a11、a12 以及将a2 分为a21、a22,该过程可以一直进行下去,直到在某次分割后的数组中元素的个数少于三个的时候,此时最多只需要一次比较就可以找出该数组中的最大和最小元素。
4.2、选择问题
使用分治法在Θ(n)时间内就可以找到中项或第k小项的算法。
设计算法来寻找数组a 的中项或第k小元素:
⑴ 当n ≤n0时,直接对数组排序,返回第k个元素即可,否则转⑵。
⑵ 把元素划分为p = n/5组,每组5个元素,不足5 个元素的忽略。
⑶ 取每组的中项,构成一个规模为p 的数组M。
⑷ 对数组M 递归求出其中项mm。
⑸ 使用mm 将原数组分成3 部分:a1 存放小于mm的元素,a2 存放等于mm的元素,a3 存放大于mm 的元素。
⑹ 分三种情况分别处理a1、a2、a3
如果|a1|≥k,对a1 递归执行算法;否则
如果|a1|+|a2|≥k,mm 是第k 小元素,返回;否则
对a3 递归执行算法。
4.3、矩阵乘法
4.3.1、传统方法
4.3.2、简单分治法
划分步骤:将矩阵A、B 分成4 个n/2×n/2 的矩阵;
治理步骤:当n>1 时,递归计算8 个n/2×n/2 的矩阵的乘积;
组合步骤:计算治理步骤得到n/2×n/2 的矩阵的和。