汉诺塔详解

【游戏规则】(摘自百度百科):汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘


在书写汉诺塔的代码前需要掌握其主要的移动思路。
3层的汉诺塔为例(代码为java):
在这里插入图片描述

解决汉诺塔的核心思路是:A柱和C柱必须畅通无阻,也就是1,2必须堆叠在B柱上,只留最下面的3,此时就可以将3从A柱移动至C柱。

解决汉诺塔就是将核心思路不断拆分实现
第一步:

  • 将A柱上的n-1个圆盘移到B柱上。
  • 将A柱上的第n个也就是最后一个圆盘移到C柱上。

第二步:

  • 将B柱上的n-1个圆盘移到C柱上。

先假定一个函数,取名为hanoi。

public void hanoi (int n,String a,String b,String c)

其四个参数为:

  • n:需要移动的汉诺塔的层数。
  • a:汉诺塔所处的开始柱。
  • b:汉诺塔在移动时借助的中转柱。
  • c:汉诺塔最终处于的柱。
hanoi(3,"塔1","塔2","塔3");

就是将3层的汉诺塔,通过塔2这个中转柱,将其从塔1转到塔3上。

构建函数的内部就需要用到递归的思路。
以3层为例,要将其3层从A柱移到C柱,按照上文的思路就需要先将A柱上的两个移动到B柱上。
在这里插入图片描述

那么想要达到上图的效果,就需要将C柱作为中转柱,B柱此时转换为目标柱
是不是有点递归的感觉了,要解决3层,就必须先解决上面的2层,要解决2层,就必须先解决1层。当1层放好,就能通过,不断返回直到问题解决。
将2层从A移动到B,又需要先解决1层。当为1层时就好办了,直接将顶上的那个从起始柱移动到目标柱。此时A柱为起始柱,C柱为目标柱

可能看到这里有些绕,我们先不去思考函数如何实现和递归的,先假定认为函数hanoi可以完成目标工作
可以书写如下代码:

 public static void hanoi(int n,String a,String b,String c) {
        if(n==1)
            System.out.println(a+"--->"+c);
        else
        {
            hanoi(n-1,a,c,b);
            System.out.println(a+"--->"+c);
            hanoi(n-1,b,a,c);
        }
    }
  • 当只有一层时,直接从起始移动到目标。
  • 参数的a,b,c不代表ABC柱,不要混为一谈,在函数里的abc始终代表三个状态柱:起始,中转,目标。
  • 例如n传入为3,那么就是先进行hanoi(n-1,a,c,b),将n-1层从A柱通过C柱转到B柱上。
    此步完成
  • 再进行System.out.println(a+“—>”+c); ,3号从A柱移动到C柱。
    在这里插入图片描述
  • 最后一步,hanoi(n-1,b,a,c) ,将这1,2层从B柱通过函数操作,转到C柱上。那么3层汉诺塔就移动完毕。
    在这里插入图片描述

上述代码已经不需要补充,虽然我们思考是假定其能实现,但程序确实通过递归的思路完成了汉诺塔的移动,先告知自己假定其完成功能是便于自己的理解。这和前文思路也是对应的,一共三步。从宏观上来看是简单明了的。难于理解的地方在于函数参数里的abc不会一直代表A柱,B柱,C柱,可能会造成混乱。同时递归的思路也有些绕。

递归的思想就体现在这三步里。

           hanoi(n-1,a,c,b);
            System.out.println(a+"--->"+c);
            hanoi(n-1,b,a,c);

首先要明确的一点!

hanoi函数中的参数a,b,c不要将其当作A柱,B柱,C柱,将其转化为三个状态量:起始,中转,目的,就会好理解一些了。

还是拿三层举例,n=3时会首先进行2层的拆分,2层会先将上面的1层从初始柱移到目标柱。

 if(n==1)
            System.out.println(a+"--->"+c);

又因为a始终代表初始柱,c始终代表目的柱,所以一直都是a—>c。这个一定要理解。
当n==1时,1就从A柱移动到C柱了。此时第一个归也就是2层汉诺塔的归就开始了。
此时执行 System.out.println(a+“—>”+c),通过idea的调试可以看到此时的abc代表什么。
在这里插入图片描述
那么a—>c就是从A柱到B柱。这里的ac也是不需要更改的,不管abc代表什么,此时都是初始柱移到目的柱。
在这里插入图片描述
抛开3,只谈1与2,2层的解决思路就是将第一层移到他的中转柱,然后2就可以移动到他的目的柱。
再看一下汉诺塔的解题步骤
第一步:

  • 将起始柱上的n-1个圆盘移到中转柱上。
  • 将起始柱上的第n个也就是最后一个圆盘移到目的柱上。

第二步:

  • 将中转柱上的n-1个圆盘移到目的柱上。

针对2层的汉诺塔,参照上图,已经实现了第一步,2落到了目标柱B柱,1落到了中转柱上。此时就需要进行第二步,将1转到目标柱上去。也就是进入了 hanoi(n-1,b,a,c)这一步,因为n=1也就没有多次递归,直接就将1从C柱移到了B柱。

此时,完成此步此步完成

顺利的按照思路走出了第一个递归(1层递归没有算进来)。要解决3层就先解决2层,解决2层就要解决1层。

递归的思路很绕,可以自己多画图多调试,尝试理解其是如何进行递又是如何进行归的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值