通俗易懂_汉诺塔(java递归实现)

汉诺塔

汉诺塔介绍

汉罗塔游戏简单来说就是,有三根柱子(记作ABC),A柱子上有从小到大的若干个圆盘,我们要怎么把A柱子上的这若干个圆盘全部挪到C,并且保证顺序还是从小到大。 规则是:挪的过程中大圆盘不能放在小圆盘上面。

图解一下(来自参考资料)

可以看到如果只有一个圆盘我们可以直接挪到C。
A -> B
在这里插入图片描述
有两个的话先把上面的圆盘挪到B,然后把最下面的圆盘挪到C,再把B的圆盘挪到C。(重点理解)
A -> B
A -> C
B -> C
在这里插入图片描述
有三个的话我们也得把最下面圆盘上面所有的圆盘挪到B,把最下面的挪到C,然后再把B的圆盘挪到C。
A(n-1) -> B
A -> C
B -> C

在这里插入图片描述

思路

可以看到有两个和三个盘子的时候思路是一样的。我们都是要先把除最下面盘子以外的所有盘子挪到B,然后最大盘子挪到C,然后再把B的盘子挪到C,齐活。 这样的话我们可以分析出不管有多少盘子,第一步我都是得把除最大盘子以外的挪到B,然后最大盘子挪到C,然后再把B的盘子挪到C。记作
A(n-1) -> B
A -> C
B -> C

先上代码(可能有些难理解)

public static void hanoiTower(int num, char a, 
char b, char c) {
        // 如果只有一个盘
        if (num == 1) {
        System.out.println("第1个盘" + a + "=>" + c);
        } else {
          
         hanoiTower(num - 1, a, c, b);
        // 把最下面的盘a - c
        System.out.println("第" + num + "个盘
        " + a + "=>"+ c);
            // 把b所有移动到c 过程使用a
            hanoiTower(num - 1, b, a,c);
        }
    }

加上递归的思路

在这里我们认为只有两种情况 第一种情况 只有一个盘子 那就直接从第一个挪到第三个, 如果是两个或者两个以上的话 先把n-1个盘子挪到B,然后把 n挪到C 然后把B的盘子挪到C。
先第一个递归走到底 这个时候就相当于只有一个盘子了,跟据递归的次数决定放在B还是C然后 回溯到上一层,此时有两个盘子在上一层时第一个盘子已经被放到B或C ,如果上一个盘子放在B,根据规则我们就会把这个放到C柱子反之放到B柱子,再进行最下面的那个递归,把B放到C。 然后一层层的回溯。

分析

递归的细节不要去深究,当初我就想着这递归是怎么实现的,细节是啥,就想在脑子里一步一步的回溯出来,但是因为里面有两个递归进行穿插,所以不好想。
我们首先知道总体思想就是分为三步,第一步是(n-1)的柱子挪到B,n挪到C,再把B挪到C。在进行第一步时我们会递归找到最上面的那一个,然后把最上面的挪到B或者C,为什么是B或者C呢,因为我们也不确定我们有多少个,第一个该放到哪。递归的作用就是帮我们把问题递出去,然后归来的是结果。(这里想不明白分析第二张图片和第三张),然后在把第现在这个圆盘放到B或C上,下面递归的作用就是判断B有没有圆盘有的话把B的圆盘放到C,这也是一个递归问题,因为回溯到后面可能B上也会放很多盘子,我们就得递归(上面得思想)把B的盘子放到C。

总结

先宏观的去看这个问题,然后一点点的深入,不要钻牛角尖。

参考资料

传送
https://www.cnblogs.com/starry-skys/archive/2020/03/23/12555829.html

秃头萌新一枚,多多关照。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值