递归-汉诺塔问题
一、这个问题,用递归来解决,不能钻牛角尖,理解每层之间的关系即可
递归,把大的问题抽象成小问题,直到这个问题不能再被抽象,即可以直接解决,然后返回上一层
二、递归三部分:
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);
}
}
}
推荐阅读