java分治_java算法:分治法

java算法:分治法

分治法用于算法设计的最重要实例:在一个程序中使用两个或多个递归调用。

例1:用分治法找到最大值

Java代码 icon_copy.gif

staticdoublemax(doublea[],intl,intr){

if(l == r){

returna[l];

}

intm = (l + r)/2;

doubleu = max(a, l , m);

doublev = max(a, m +1, r);

if(u > u){

returnu;

}else{

returnv:

}

}

static double max(double a[], int l, int r){

if(l == r){

return a[l];

}

int m = (l + r)/2;

double u = max(a, l , m);

double v = max(a, m + 1, r);

if(u > u){

return u;

}else{

return v:

}

}

分治法比简单的循环算法更加快捷。

一个有趣的例子:3个柱子和N个与柱子配套的盘子,盘子大小不同,从N(大)到1(小)的顺序放在其中一个柱子上。任务:移动到最右边的柱子上。一次只能移动一个,大的盘子不能放在小的盘子上。

例2:汉诺塔问题的递归分治法所产生的解决方法要移动2的N次方-1次。

Java代码 icon_copy.gif

staticvoidhannoi(intn,intd){

if(n ==0){

return;

}

hanoi(n -1, -d);

shift(n, d);

hanoi(n -1, -d);

}

static void hannoi(int n, int d){

if(n == 0){

return;

}

hanoi(n - 1, -d);

shift(n, d);

hanoi(n - 1, -d);

}

例3:用分治法画刻尺

Java代码 icon_copy.gif

staticvoidrule(intl,intr,inth){

intm = (l + r)/2;

if(h >0){

rule(l, m, h -1);

mark(m, h);

rule(m, r, h -1);

}

}

static void rule(int l, int r, int h){

int m = (l + r)/2;

if(h > 0){

rule(l, m, h - 1);

mark(m, h);

rule(m, r, h - 1);

}

}

对于任意给定的i,有更简单的方法来计算第i个标记长度:即i的二进制尾数0的个数。

Java代码 icon_copy.gif

00001

000101

00011

001002

00101

001101

00111

010003

01001

010101

01011

011002

01101

011101

01111

100004

10001

100101

...

0 0 0 0 1

0 0 0 1 0 1

0 0 0 1 1

0 0 1 0 0 2

0 0 1 0 1

0 0 1 1 0 1

0 0 1 1 1

0 1 0 0 0 3

0 1 0 0 1

0 1 0 1 0 1

0 1 0 1 1

0 1 1 0 0 2

0 1 1 0 1

0 1 1 1 0 1

0 1 1 1 1

1 0 0 0 0 4

1 0 0 0 1

1 0 0 1 0 1

...

例4:画刻尺的非递归程序

Java代码 icon_copy.gif

staticvoidrule(intl,intr,inth){

for(intt =1, j =1; t <= h; j += j, t++){

for(inti =0; l +j + i <= r; i += j + j){

mark(l + j + i, t);

}

}

}

static void rule(int l, int r, int h){

for(int t = 1, j = 1; t <= h; j += j, t++){

for(int i = 0; l +j + i <= r; i += j + j){

mark(l + j + i, t);

}

}

}

一般来说,许多递归程序取决于解决子问题的特定顺序,但对于另一些算法(用分治法找最大值),则与解决子问题的顺序无关。对于这样的算法,唯一的限制条件是我们再解决主问题之前必须先解决子问题。什么时候可以重排计算是很重要的。在考虑并行处理器上实现算法时,这个问题就更重要了。自底向上的方法与一般算法设计的思路是一样的,即总先解决那些容易处理的子问题,然后把这些解结合起来,从而解决稍大的子问题,直到整个问题得于解决,这种方法就是分治法。

快速排序和折半查找是基本的分治法思想的变体,即把问题分成大小为k-1和N-k的子问题,k值由输入决定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值