> 文档中心 > 汉诺塔问题解析 - 浅显易懂

汉诺塔问题解析 - 浅显易懂

文章目录

    • 汉诺塔问题
    • 编程要求
    • 解题思路
    • 代码实现
    • 总结

汉诺塔问题

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

——来自于百度百科

编程要求

  • 有A、B、C三根柱子,A为起始柱,B为辅助柱,C为目标柱,还有若干圆盘,圆盘按上小下大的顺序堆放在A柱上,从上到下依次为每一个圆盘标号为 1 到 n
  • 输入圆盘数,要求将A柱的圆盘移动到C柱,一次只能移动一个,但是要保证不能把大圆盘放在小圆盘上面
  • 输出每一个圆盘每一步移动的过程,比如:1号圆盘从 A -> C
  • 提示:利用递归解决

解题思路

从宏观的角度思考问题,不要试图去理解每一个圆盘的移动过程

首先,如果只有一个圆盘,那么就可以直接移动到目标柱子上,无需借助辅助柱,这一点就可以作为递归函数的终止条件

如果圆盘数量 n >= 2的时候,可以分3步考虑:

1.把n上面的所有圆盘移动到B柱,C作为辅助,此时A是起始柱,B是目标柱,C只是作为辅助柱

2.把最大的圆盘n直接从A移动到C柱

3.把B柱上的圆盘全部移到C柱,A作为辅助,此时B是起始柱,C是目标柱,A只是作为辅助柱

从宏观角度来看就是这3步,不需要去考虑n以外的圆盘怎么移动,因为每进入一次递归,起始柱、目标柱和辅助柱都会变化,我们很难分清每一步是从哪个柱子到哪个柱子的

那么n-1个圆盘的移动交给递归方法去解决即可,因此我们仅需要写出终止条件时的移动以及 n>=2时的3个步骤即可

宏观图示如下:

在这里插入图片描述

我们就可以利用递归来实现这段代码

我们首先需要定义一个方法

方法的功能是:传入n个圆盘,就能根据汉诺塔的规则,把目标盘子从 a -> c, b是辅助柱

在写递归的时候,我们只需要想着如何调用他来实现上述功能就好了,剩下的交给程序

代码实现

public class Test {    public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("请输入圆盘的数量"); int num = in.nextInt(); hanoi(num, 'A', 'B', 'C');//最开始以A、B、C分别作为起始、辅助、目标柱    }    //汉诺塔方法实现    public static void hanoi(int num, char a, char b, char c){      //只有移动一个圆盘时 if (num == 1) {   //不需要经过b,直接从a -> c     System.out.println("第" + num + "个圆盘从" + a + " -> " + c); }else{   //n >= 2时,核心步骤1:把上面的num-1个圆盘从a -> b,c作为辅助     hanoi(num - 1, a, c, b);   //核心步骤2:此时a上就剩下第num个圆盘,直接从a -> c     System.out.println("第" + num + "个圆盘从" + a + " -> " + c);   //核心步骤3:此时再把b上的这n-1个圆盘从b -> c,a作为辅助     hanoi(num - 1, b, a, c); }    }}//执行结果请输入圆盘的数量31个圆盘从A -> C2个圆盘从A -> B1个圆盘从C -> B3个圆盘从A -> C1个圆盘从B -> A2个圆盘从B -> C1个圆盘从A -> C

总结

汉诺塔问题的代码,一定要从宏观角度去研究问题,如果从微观角度去看,研究每一个圆盘是如何移动,很难理解。其次,多用画图来帮助自己理解问题!!