boxmoe_header_banner_img

欢迎来到YaeMiko小站

加载中

文章导读

汉诺塔的递归


avatar
Samele 2025-05-10 26

背景:

在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。

印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。

不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。

僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

 

汉诺塔就相当于有ABC三根柱子,目标是要将A柱的所有金片移动到C柱子。移动过程中必须遵循小片在大片上面

这是我见过的比较诡异的递归题目,难度在于他递归调用时候参数的变换。结合示例代码来看这个问题

 

public class HanoiTower {

    public static void main(String[] args) {
        //盘子的数量,按照最简单的方式来理解,比如有两个金片(可以将最大的金片当作第一个,上面所有的金片看成第二个金片)
        int plate = 2;
        //调用move方法移动金片
        new HanoiTower().move(plate,"A","B","C");
    }

    //递归的移动方法。参数一次为:金片的个数,从那个柱子移动,经过哪个柱子,最终想要移动到的柱子
    public void move(int n, String from, String aux, String to) {
        //退出条件
        //移动第一个金片,n=1,这里可以做个假设,比如只有一个金片,那么带入到这个方法后,直接是从A移动到C,返回递归方法。
        //这也是整个递归的输出的第一句话
        if (n == 1) {//金片数量为1,移动后达成递归条件返回
            System.out.println("移动 盘子" + n + "从" + from + "到" + to);
            return;
        }
        //递归调用,移动该金片下面大的金片,从A移动到B,借助C,这是移动顶端金片前的一部操作
        move(n - 1, from, to, aux);
        //当第一枚金片移动到C后,开始倒叙输出,将第2枚金片
        System.out.println("将盘子" + n + "从" + from + "移动到"+ to);
        //收尾工作,就是最底下那枚金片移动到C柱后,需要将剩下的金片从辅助柱子移动到目标柱子。。
        move(n-1,aux,from,to);
    }
}




实话说如果没有看到其他人的解题方法,我也是想不到居然是这样操作。不过递归的整体逻辑还是没有变化,

1、设置递归退出条件

2、设置递归尝试的逻辑

3、尝试逻辑不断逼近递归退出条件,待达成退出条件后,开始递归出栈。

 

汉诺塔的递归代码非常的简短,但是确实难以理解。

我认为最好的办法就是缩减金片的数量,假设1枚、2枚、3枚金片进行逐步推理。 测试通过后再进行累加。验证



评论(已关闭)

评论已关闭