常用算法之分治算法(如何解决汉诺塔问题)

1.什么是分治算法

“分治”从字面上解释就是“分而治之”,将一个复杂的问题分解成为两个或者更多的相同或者相似的子问题,再把子问题分成更小的子问题,直到最后的子问题简单到可以直接求解,原问题的解就是子问题解的合并。

复杂问题 -> 子问题 -> 更小的子问题(足以解决)

2.分治算法的基本步骤

1.分解:将原问题分解为若干个规模较小,相互独立,和原问题形式相同子问题

2.解决:  若子问题规模较小,而容易被解决的直接解决,否则递归解决各个子问题

3.合并:  将各个子问题的解合并为原问题的解

3.汉诺塔问题

简单介绍:

存在三根柱子(ABC),柱子上存在着若干小圆盘,要求把小圆盘从最左边的柱子搬运到最右边,要求小的圆盘需要在大的盘子上面,上面的盘比下面的盘先动(所有圆盘的初始位置在最左边)

分析思路:

1.如果只有一个盘,从A杆到C杆直接 A->C即可

2.如果有两个盘的话,先把上面一个盘 A->B,然后把下面一个盘 A->C,然后把上面一个盘从B->C

3.如果有两个盘及其以上,可以将所有的盘看做两部分(一部分是最下面一个,一部分是上面的所有个)

4.先把上面的所有盘 A->B,最下面这个盘从B->C,然后把B杆中的所有盘搬运到C杆


 

4.汉诺塔代码(递归解决)

/**
 * 汉诺塔问题
 * */
public class Hanoitower {
    public static void main(String[] args) {
        hanoiTower(5,'A','B','C');
    }
    //汉诺塔的移动方案
    //使用分治算法
    public static void hanoiTower(int num,char a,char b,char c){
        if(num==1){
            System.out.println("第1个盘从"+a+"->"+c);
        }else{
            //如果我们有n >= 2的情况,我们总是可以看做两个盘 1.最下面的一个盘 2.上面的所有盘
            //1.先把上面所有盘 a->b
            hanoiTower(num-1,a,c,b);
            //2.最下面的盘 a->c
            System.out.println("第"+num+"个盘从"+a+"->"+c);
            //3.b->c 再把b中的盘子移动到c
            hanoiTower(num-1,b,a,c);
        }
    }
}

 

5.测试结果

第1个盘从A->C
第2个盘从A->B
第1个盘从C->B
第3个盘从A->C
第1个盘从B->A
第2个盘从B->C
第1个盘从A->C
第4个盘从A->B
第1个盘从C->B
第2个盘从C->A
第1个盘从B->A
第3个盘从C->B
第1个盘从A->C
第2个盘从A->B
第1个盘从C->B
第5个盘从A->C
第1个盘从B->A
第2个盘从B->C
第1个盘从A->C
第3个盘从B->A
第1个盘从C->B
第2个盘从C->A
第1个盘从B->A
第4个盘从B->C
第1个盘从A->C
第2个盘从A->B
第1个盘从C->B
第3个盘从A->C
第1个盘从B->A
第2个盘从B->C
第1个盘从A->C
发布了193 篇原创文章 · 获赞 70 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/Lzinner/article/details/103613604