图解汉诺塔问题(递归求解)

图解汉诺塔问题(递归求解)汉诺塔 汉诺塔 TowerofHanoi 源于印度传说中 大梵天创造世界时造了三根金钢石柱子 其中一根柱子自底向上叠着 64 片黄金圆盘 大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上 并且规定 在小圆盘上不能放大圆盘 在三根柱子之间一次只能移动一个圆盘 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 引用维基百科单看这个问题描述有点让人抓瞎 这是当然 无论多么简单的问题描述

汉诺塔:汉诺塔(Tower of Hanoi)源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。                        –引用维基百科

单看这个问题描述有点让人抓瞎,这是当然,无论多么简单的问题描述,在没有建立具体地模型之前都是让人不知所云的,仅仅用生活中的语言去描述一些数学或算法问题往往会让听者产生理解偏差,这也和每个的理解能力和思维方式有很大关系,这就显示出数学的强大了,数学让问题不再模糊,参数和公式组成的模型让问题不再有理解偏差和误区,只可惜数学没学好,看来以后还得回来把高数、概率论这些给补回来。

说了一些题外话,下面来对汉诺塔问题进行解释和建立模型

图解汉诺塔问题(递归求解)

    这是示意图,a是起始柱,c是目标柱,b起到中转作用

    在进行转移操作时,都必须确保大盘在小盘下面,且每次只能移动一个圆盘,最终c柱上有所有的盘子且也是从上到下按从小到大的顺序。

    很多时候看到这些蛋疼和矫情操作就觉得数学家真是思维清奇、智慧如海,嗯还有吃饱了撑的,某兄台邪魅地一笑,道:直接把c和a交换位置不就行了,我想这位兄台以后或成大器或被人打死。

    问题看起来并不复杂,当a柱子上只有一个盘子时只要把那个盘子直接移到c就行了,

    有两个盘子的话把1号盘先移到b柱,在把2号盘移到c柱,最后把b柱上的1号盘移到c柱就行了,

    但现在我们要移动的是64个盘子,要是我们自己手动操作,那画面会很美,闲着无聊的人可以试试,推荐去网上找找汉诺塔的小游戏,这也可以帮你加深对这个问题的理解。

下面我用图来描述64个盘子的转移流程

  图解汉诺塔问题(递归求解)

    这里我们先把上方的63个盘子看成整体,这下就等于只有两个盘子,自然很容易了,我们只要完成两个盘子的转移就行了,好了现在我们先不管第64个盘子,假设a柱只有63个盘子,与之前一样的解决方式,前62个盘子先完成移动目标。

    嗯,就这样一步步向前找到可以直接移动的盘子,62,61,60,……,2,1,最终,最上方的盘子是可以直接移动到c柱的,那就好办了,我们的2号盘也能完成向c柱的转移,这时c柱上时已经转移成功的2个盘,于是3号盘也可以了,一直到第64号盘。

    下面是我用C#实现的代码:

using System; using System.Collections.Generic; namespace 汉诺塔问题_递归解决 { class Program { static void Main(string[] args) { HanNuo(64, 'a', 'b', 'c'); Console.ReadKey(); } ///  /// 汉诺塔问题解决方法 ///  /// 汉诺塔的层数 /// 承载最初圆盘的柱子 /// 起到中转作用的柱子 /// 移动到的目标柱子 static void HanNuo(int n, char a, char b, char c) { if (n == 1) //这也是递归的终止条件 { Console.WriteLine("将盘子[{0}]从 {1} -----> {2}", n, a, c); //控制台输出每次操作盘子的动向 } else { HanNuo(n - 1, a, c, b); //将a柱子上的从上到下n-1个盘移到b柱子上 Console.WriteLine("将盘子[{0}]从 {1} -----> {2}", n, a, c); HanNuo(n - 1, b, a, c); //将b柱子上的n-1个盘子移到c柱子上 } } } }

       代码很简洁,可能对于递归不是很理解的同学觉得有些吃力,下面我来具体解释下递归的流程。

       当n=64时,前63个要想办法成功移动到b柱上,64号是Boss,他不管上面的63个小弟用什么办法,我可以先等着,前面63个小弟可以利用我的c柱,于是64号在等着上面63号完成移到b柱,现在63是临时老大,他也想去c柱,于是他命令前62号移到b柱,他等着,62号也采取之前两个的做法,于是这个命令一直往前传,没办法,上面被压着自己也没法动啊。

        终于到了1号,他是现在唯一能动的,于是1号移动到了b柱,好了,2号可以到c柱,2第一个到目的地,心里十分激动,我都到c柱,舒服。不过当他看到a柱上的3号时,猛然一惊,我还有个上司,好吧得完成任务啊,于是让1号移到c柱,3号可以到b柱了,之后1号和2号在想办法到b柱,于是1,2,3号在b柱,4号一看很满意,但我得到b柱啊,嗯,1,2,3号你们按照刚才的办法到c柱,空出b柱给我。唉,接着折腾,后面的5号一直到63号都是这么折腾的,终于前63号移动到b柱,64号直接跑到了c柱,他觉得这些小弟办事效率真不行,不过他还是招呼小弟到c柱。

     于是剩下在b柱的63个小弟还要再干一遍他们在a柱上干的事,这里来看,1号操作的频率是最高的,而64号只要移动一次就行了,要是在现实中让人这么去干,估计早就被逼疯了。

      如果真要解释代码的每一步执行过程,那会很乱,两层递归,最后自己也会被绕的晕头转向,这个时候只要理解递归最终的解决的问题是什么就行了,中间的事交给程序,递归可以很绕也可以很直接,我们按照最直接的理解就行了。

  最后关于递归算法,这中解决问题的方法也只有计算机才喜欢,我们虽然看着代码很简单,但真要深入理解也是很费脑细胞的,不过递归确实有中数学上的简洁美和逻辑美。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/206432.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午3:42
下一篇 2026年3月19日 下午3:43


相关推荐

  • Ant 执行 YUICompressor

    Ant 执行 YUICompressorAnt执行YUICompressor任务压缩JavaScript和CSS文件,解决中文乱码问题,增加源文件字符编码集设定标签:javascriptantcss任务encodingnull2012-04-0510:465376人阅读评论(4)收藏举报分类:Java(14)Ant版权声明:本文为博主原创文章,未经博主允许…

    2022年7月18日
    15
  • 生成pdf有的内容显示不出来_为什么ug程序生成导轨不显示

    生成pdf有的内容显示不出来_为什么ug程序生成导轨不显示TFRecord  TensorFlow提供了TFRecord的格式来统一存储数据,TFRecord格式是一种将图像数据和标签放在一起的二进制文件,能更好的利用内存,在tensorflow中快速的复制,移动,读取,存储等等。  TFRecords文件包含了tf.train.Example协议内存块(protocolbuffer)(协议内存块包含了字段Features)。我们可以写一

    2025年8月12日
    3
  • GoLand 2022.01.21 激活码_在线激活2022.02.01「建议收藏」

    (GoLand 2022.01.21 激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~CJM5ZJBPHS-eyJsaWNlbnNlSWQiOi…

    2022年3月31日
    83
  • postman接口自动化测试实战_postman是干嘛的

    postman接口自动化测试实战_postman是干嘛的Apifox介绍Apifox是API文档、API调试、APIMock、API自动化测试一体化协作平台,定位Postman+Swagger+Mock+JMeter。通过一套系

    2022年7月30日
    14
  • python数字推盘_从零开始学编程做游戏:一个文科生策划的14周

    python数字推盘_从零开始学编程做游戏:一个文科生策划的14周点击”humansflee”按钮则人类移动一回合,点击”zombiesstalk”按钮则僵尸移动一回合。它们采取的寻路策略都是广度优先搜索。游戏不会结束,你可以在这个沙盒中给自己安排胜利条件。布置各种各样的场面看着它们行动,也还能支撑个半小时的乐趣,是到目前为止制作的可玩性最强的游戏……同样的,这个游戏也是一个具有充分扩展性的游戏。感染者会不会转化成僵尸?人类能不能拿到武器反击僵尸?僵…

    2025年6月22日
    5
  • 递归改成循环_递归比循环效率高吗

    递归改成循环_递归比循环效率高吗Java递归,递归改循环为什么大家都说不建议用递归?递归容易造成栈溢出,在jdk1.5前虚拟机给每个栈桢的运行空间128kb,在1.5以后为1m的运行空间.递归是指先进后出,也就是说第一进栈的对象会最后一个出站,然后栈桢的空间只有1m,生产环境的数据需要递归的深度,一般情况下我们无法通过测试来进行模拟。所以对于递归的深度不可把控的情况下,是有栈溢出的风险。一个简单的例子测试递归的深度递…

    2025年12月16日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号