1、概述
在计算机科学中,分治法是一种很重要的算法,字面的解释就是”分而治之“,就是把一个问题划分成两个或多个相同或相似的子问题,再把子问题划分成更小的子问题…只到问题解决
这个技巧是很多高效的算法的基础,如排序算法中的快排、归并排序等等。
分治算法可以求解的一些经典问题 二分搜索
大整数乘法
棋盘覆盖
合并排序
快速排序
线性时间选择
最接近点对问题
循环赛日程表
汉诺塔
任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。
2、 基本思想和策略
分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
分治的策略是:对于一个规模为n的问题
分治算法在每一层递归上都有三个步骤
1)、分解:将原问题分解成若干个规模较小,相互独立,与原问题相同的子问题
2)、解决:若子问题规模较小而容易被直接解决,否则递归的解决各个子问题
3)、合并,将各个子问题的解合并为原问题的解
3、分治算法的最佳实践:汉诺塔问题
汉诺塔游戏的演示和思路分析
1)、如果是有只一个:A->C
如果有n>=2情况
2)、先把最上面的盘A->B
3)、把最下面的盘A->C
4)、把B塔的所有盘从B->C
汉诺塔的代码实现:
public class Hanoitower {
static int count=0;
public static void main(String[] args) {
hanoitower(5, 'A', 'B', 'C');
System.out.println(count);
}
/**
* 汉诺塔问题 有num个盘子在a柱子上,我们需要将其全部移动到c柱子 其中过程需要使用到b柱子
* @param num 汉诺塔的数量
* @param a 第一个柱子
* @param b 第二个柱子
* @param c 第三个柱子
*/
public static void hanoitower(int num,char a,char b,char c){
count++;
if(num==1){
System.out.println("将第"+num+"个盘子从"+a+"移动到"+c);
}else{
//如果num>2的情况下,我们可以总是看作两个盘,最上面的num-1个 和最下面的1个
//将最上面的所有盘A->B 需要借助到c盘
hanoitower(num-1, a, c, b);
//将最下面的一个盘A->c
System.out.println("将第"+num+"个盘子从"+a+"移动到"+c);
//将所有的盘从B->C
hanoitower(num-1, b, a, c);
}
}
}
代码很简单,思路也很容易,但是如果深入去分析,就有点不好理解,我们就可以看作是将整个问题划分成了这几个小问题即可。