博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java算法:分治法
阅读量:5231 次
发布时间:2019-06-14

本文共 2183 字,大约阅读时间需要 7 分钟。

java算法:分治法

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

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

Java代码
  1. static double max(double a[], int l, int r){   
  2.     if(l == r){   
  3.         return a[l];   
  4.     }   
  5.     int m = (l + r)/2;   
  6.     double u = max(a, l , m);   
  7.     double v = max(a, m + 1, r);   
  8.     if(u > u){   
  9.         return u;   
  10.     }else{   
  11.         return v:   
  12.     }   
  13. }  
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代码
  1. static void hannoi(int n, int d){   
  2.     if(n == 0){   
  3.         return;   
  4.     }   
  5.     hanoi(n - 1, -d);   
  6.     shift(n, d);   
  7.     hanoi(n - 1, -d);   
  8. }  
static void hannoi(int n, int d){	if(n == 0){		return;	}	hanoi(n - 1, -d);	shift(n, d);	hanoi(n - 1, -d);}

例3:用分治法画刻尺

Java代码
  1. static void rule(int l, int r, int h){   
  2.     int m = (l + r)/2;   
  3.     if(h > 0){   
  4.         rule(l, m, h - 1);   
  5.         mark(m, h);   
  6.         rule(m, r, h - 1);   
  7.     }   
  8. }  
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代码
  1. 0 0 0 0 1  
  2. 0 0 0 1 0  1  
  3. 0 0 0 1 1  
  4. 0 0 1 0 0  2  
  5. 0 0 1 0 1    
  6. 0 0 1 1 0  1  
  7. 0 0 1 1 1    
  8. 0 1 0 0 0  3  
  9. 0 1 0 0 1  
  10. 0 1 0 1 0  1  
  11. 0 1 0 1 1     
  12. 0 1 1 0 0  2  
  13. 0 1 1 0 1    
  14. 0 1 1 1 0  1  
  15. 0 1 1 1 1  
  16. 1 0 0 0 0  4  
  17. 1 0 0 0 1  
  18. 1 0 0 1 0  1  
  19. ...  
0 0 0 0 10 0 0 1 0  10 0 0 1 10 0 1 0 0  20 0 1 0 1 0 0 1 1 0  10 0 1 1 1 0 1 0 0 0  30 1 0 0 10 1 0 1 0  10 1 0 1 1  0 1 1 0 0  20 1 1 0 1 0 1 1 1 0  10 1 1 1 11 0 0 0 0  41 0 0 0 11 0 0 1 0  1...

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

Java代码
  1. static void rule(int l, int r, int h){   
  2.     for(int t = 1, j = 1; t <= h; j += j, t++){   
  3.         for(int i = 0; l +j + i <= r; i += j + j){   
  4.             mark(l + j + i, t);   
  5.         }   
  6.     }   
  7. }   
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值由输入决定。

转载于:https://www.cnblogs.com/wuyida/archive/2012/11/01/6301146.html

你可能感兴趣的文章
RabbitMQ、Redis、Memcache、SQLAlchemy
查看>>
linux查看端口占用
查看>>
Sql常见面试题 受用了
查看>>
知识不是来炫耀的,而是来分享的-----现在的人们却…似乎开始变味了…
查看>>
CSS背景颜色、背景图片、平铺、定位、固定
查看>>
口胡:[HNOI2011]数学作业
查看>>
我的第一个python web开发框架(29)——定制ORM(五)
查看>>
中国剩余定理
查看>>
基础笔记一
查看>>
uva 10137 The trip
查看>>
Count Numbers
查看>>
编写高质量代码改善C#程序的157个建议——建议110:用类来代替enum
查看>>
网卡bond技术
查看>>
UITabbarController的UITabbarItem(例:"我的")点击时,判断是否登录
查看>>
UNIX基础知识之输入和输出
查看>>
【洛谷 P1666】 前缀单词 (Trie)
查看>>
数据库锁机制及乐观锁,悲观锁的并发控制
查看>>
图像处理中双线性插值
查看>>
RobHess的SIFT代码解析之RANSAC
查看>>
03 线程池
查看>>