分治的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。找出各部分的解,然后把各部分的解组合成整个问题的解。
1、解决算法实现的同时,需要估算算法实现所需时间。分治算法时间是这样确定的:
解决子问题所需的工作总量(由 子问题的个数、解决每个子问题的工作量 决定)
合并所有子问题所需的工作量
2、分治法是把任意大小问题尽可能地等分成两个子问题的递归算法
3、分治的具体过程:
begin {开始}
if ①问题不可分 then ②返回问题解
else begin
③从原问题中划出含一半运算对象的子问题1;
④递归调用分治法过程,求出解1;
⑤从原问题中划出含另一半运算对象的子问题2;
⑥递归调用分治法过程,求出解2;
⑦将解1、解2组合成整修问题的解;
end;
end; {结束}
一般在分治法中会用到递归,如果觉得递归太浪费空间,也可以用循环..
具体流程算法如下:
if 问题不可分 then 求解 | if s=t then r1[s]:=r[s] |
else | else |
(1)分出问题的一个子问题1,并求解子问题1(一般用递归---调用自身) | mergesort(r,r2,s,(s+t)div 2);-------递归 |
(2)分出问题的一个子问题2,求解子问题2(一般用递归---调用自身) | mergesort(r,r2,(s+t)div 2,t);------递归 |
(3)合并子问题1和子问题2 | merge(r2,s,(s+t)div 2,t,r1);-----综合 |
在数据结构中,快速排序和合并排序都是采用了分而治之的思想,下面具体用快速排序来让大家更了解分治算法.
下面是程序,具体算法思想在注释中会给出:
package sf.fenzhi;
public class FenZhiTwo{
public int b[]=null;
public FenZhiTwo(int b[]){
this.b=b;
}
public void sort(int low,int up){//分治算法实现快速排序的函数------其中采用了递归算法.
if(low>=up) return;//-------问题不可分解,给出结果(这里是返回)
int split=sortOne(low,up);//递归当前一步要做的
sort(low,split-1);//递归---解决子问题
sort(split+1,up);//递归---解决子问题
//由于这里是就地排序,所以不需要综合,这一步在这里不要,一般情况是要的.
}
public int sortOne(int low,int up){
int temp=b[low];
int i=low;
int j=up;
while(i<j){
while(temp<b[j] && i<j) j--;
b[i]=b[j];
while(temp>=b[i] && i<j) i++;
b[j]=b[i];
}
b[j]=temp;
return j;
}
public void printThis(){
int length=b.length;
for(int i=0;i<length;i++){
System.out.print(b[i]+" ");
}
System.out.println();
}
public static void main(String[] args){
int b[]={2,9,5,6,10,3,8,7,4};
FenZhiTwo fen=new FenZhiTwo(b);
System.out.println("before of sort:");
fen.printThis();
fen.sort(0,b.length-1);
System.out.println("after of sort:");
fen.printThis();
}
}
看上面的程序不难看出,其实很多递归算法和分治算法都是在同一问题中.
但要注意的是他们两是从不同的角度去分析问题的,递归是以调用自身为基础,实现把问题分解成很多相同的子问题来解决,而分治算法不一定一定要用递归,可以用循环,他只是要实现一钟分而治之的思想.
下面留个练习,用循环来实现分治算法.
希望大家都交流.