1.分治法的思想:
将一个输入规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同,然后递归的求解这些子问题,最后用适当的方法将各子问题的解合并成原问题的解。
2.分治法的步骤:
分(divide) 二分为主
治(conquer) 递归调用,当规模足够小时直接处理
组(combine)
3.抽象化控制
procedure DANDC(p,q) global n, A(1:n);
integer m, p, q; //1≤p≤q≤n// if SMALL(p,q) //判断输入规模q-p+1是否足够小,可直接求解
then return(G(p,q))
else m=DIVIDE(p,q)
return(COMBINE( DANDC(p,m), DANDC(m+1,q)))
endif
end DANDC
4.解决问题
(1)二分检索(就是查找一个二分检索树)
* 一定是有序的
* 任何一种以比较为基础的算法,其最坏情况下的计算时间都不可能低于O(logn),也就是不可能存在其最坏情况下计算时间比二分检索算法的计算时间数量级还低的算法。 结论:二分检索是解决检索问题的最优的最坏情况算法。
(2)归并分类
给定一个含有n个元素的集合, 把它们按一定的次序分类(如非降次序)
(先蓝色线往下递归)
Procedure MERGESORT(low,high)
int low, high, mid;
if (low<high)
then mid← (low+high)/2
call MERGESORT(low,mid)
call MERGESORT(mid+1,high)
call MERGE(low,mid,high)
endif
end MERGESORT
procedure MERGE(low, mid, high)
int h, j, k, low, mid, high;
global A(low : high);
local B(low : high);
h ← low; i ← low; j ← mid+1;
while (h≤mid and j≤high) do
if (A[h] ≤A[j]) then B[i] ← A[h]; h ← h+1;
else B[i] ← A[j]; j ← j+1;
endif
i ← i+1;
repeat
if (h>mid) then for k←j to high do B[i]←A[k];i←i+1 repeat
else for k←h to mid do B[i]←A[k];i←i+1 repeat
for k ← low to high do A[k] ← B[k] repeat
end MERGE
*任何以关键字比较为基础的分类算法,最坏情况下的时间下界都是Ω(nlogn),
因此从数量级的角度上看, 归并算法是最坏情况下的最优算法。