欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

递归-汉诺塔问题

程序员文章站 2022-04-13 12:19:58
...

递归-汉诺塔问题

一、这个问题,用递归来解决,不能钻牛角尖,理解每层之间的关系即可

递归,把大的问题抽象成小问题,直到这个问题不能再被抽象,即可以直接解决,然后返回上一层

二、递归三部分:

1、定义函数: 调用自身函数

2、调用之间的关系

3、什么时候有基值

三、3个盘子举例子

定义函数:doTower(top,from,middle,to)       //从from 移动  top个盘子  到 to

这三根柱子分别是  from (原点 )    middle(中转点)   to(目标点)  

第一层

递归-汉诺塔问题

1、移动三个盘子  from --> to

①不能移动两个盘子,所以抽象问题,把前fromt两个盘子移动到中间 ,也就是(top-1) 个盘子     top --->   middle  

递归-汉诺塔问题

②把from 剩下的一个盘子放到目标  to   from -->to   因为是一个盘子,所以直接移动不用抽象问题

递归-汉诺塔问题

③不能移动两个盘子,所以抽象问题,把中间的盘子移动到目标柱子 ,     middle --->   to

递归-汉诺塔问题

第二层、

首先对第一层①抽象问题解决,(top-1)个盘子 从from -->middle,所以目标点变为了middle ,to目标点变为 了中转点

递归-汉诺塔问题

form top-1 个移动到  to 

①因为只两个不能直接 from -->  to 所以先吧top-1 个盘子移动到middle    因为是一个盘子这个就是基值(最基本的操作) 所以直接移动  frop-1   from->middle

递归-汉诺塔问题

② 把剩下的一个盘子  from --> to  因为是一个盘子直接移动

递归-汉诺塔问题

③然后吧middle-->to  因为 middle 就一个盘子,又遇到了基值(最基本的操作),直接移动,这样就完成了第一层①的抽象操作

递归-汉诺塔问题

2、然后完成第一层②的操作,把middle->to,所以 中转middle点变为了原点,开始点from变为了中转点middle

递归-汉诺塔问题

不能直接移动两个盘子,所以分解问题

① top-1 个盘子  from--> middle,由于一个盘子,直接移动

递归-汉诺塔问题

② from-to   由于from也是一个盘子,是基本操作,直接移动

递归-汉诺塔问题

③middle-->to  由于是一个盘子,直接移动

递归-汉诺塔问题

总体思路,把大问题分解成小问题,一直循环,直到不能再分集,然后操作最基础的操作

对于每一层移动的盘子和移动的位置不同,所以  from  to   middle 是一只变化的,他们的位置是相对的,所以这个得分析好

分析3层的关系即(算上基值)  每一层调用的关系

代码如下:

public class Hannuo_3 {
    public static int nDisks = 3;
    public static void main(String[] args){
        doTower(nDisks,'A','B','c');
    }
    public static void  doTower(int topN,char from,char inner,char to){
        if (topN==1)
            System.out.println("from "+from+"-----> to"+to);
        else {
            doTower(topN-1,from,to,inner);
            System.out.println("from "+from+"-----> to"+to);
            doTower(topN-1,inner,from,to);
        }
    }
}

 

相关标签: 数据结构与算法