数据结构经典算法学习之河内之塔(汉诺塔)
2016-12-28 12:09
393 查看
河内之塔 (汉诺塔)
故事背景:河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。
问题描述:
有一个梵塔,塔内有三个座A、B、C,A座上有诺干个盘子,盘子大小不等,大的在下,小的在上(如图)。
把这些个盘子从A座移到C座,中间可以借用B座但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。
描述简化:
把A柱上的n个盘子移动到C柱,其中可以借用B柱。
问题手拆:
设定有n个盘子在A上
则:当n=1,A——>C
当n=2,A——>B,A——>C,B——>C
当n=3,A——>C,A——>B,C——>B,A——C,B——>A,B——C,A——>C
当n=4,A——>B,A——>C,B——>C,A——B,C——>A,C——B,A——>B(至此将顶部3个盘子都移到了B上),A——>C,B——>C,B——>A,C——A,B——>C,A——B,A——>C,B——>C
当n=5,A——>C,A——>B,C——>B,A——C,B——>A,B——C,A——>C(至此将顶部3个盘子都移到了C上),A——>B,C——>B,C——>A,B——A,C——>B,A——C,A——>B,C——>B(至此将顶部4个盘子都移到了B上),A——>C(这里博主就不往下面写了,交给读者们吧,我脑子有点累。。。思路:此时B上有4个盘子,C上有一个最大的盘子,假设将C上的盘子忽略掉存在,因为它已经是最大的了,上面放任何一个盘子都不会违反规则;至此将B的情景放在上面n=4的那一步中,假设B就是A,那么继续进行,将B的最大盘子放到C上;至此再类推到第二步n=3时...)...........
当n=....
问题思考:
其实上面的问题,大家经过思考会发现,不管过程如何曲折,想要把A上n个盘子移到C上,就必须要把前n-1个盘子先放到B上,然后将最大的盘子放到C上;之后再将C上的固定了的盘子假设不存在,此刻B上的盘子当做上一步的A盘子,继续一样的思路进行(其实仔细看上面的问题手拆,会发现规律,前几步都是重复的,后几步其实只是把A换成了B或者A换成了C)。另外可能网上许多的类似关于汉诺塔的解释方法,都没有详细多少如何把n-1个盘子放到B上呢?其实给大家提供一个解决思路:想要将n-1个盘子放到B上,那就必须先将n-2个盘子移到C处,再将最大的盘子从A移到B处。其实说白了仍然是汉诺塔的递归)
代码实现(网上有很多一样的大致实现,但都是一个思路的实现,具体到函数层的实现并没有写,博主这里有时间给大家写一个做参考,暂时先放个雷同的吧):
故事背景:河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。
问题描述:
有一个梵塔,塔内有三个座A、B、C,A座上有诺干个盘子,盘子大小不等,大的在下,小的在上(如图)。
把这些个盘子从A座移到C座,中间可以借用B座但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。
描述简化:
把A柱上的n个盘子移动到C柱,其中可以借用B柱。
问题手拆:
设定有n个盘子在A上
则:当n=1,A——>C
当n=2,A——>B,A——>C,B——>C
当n=3,A——>C,A——>B,C——>B,A——C,B——>A,B——C,A——>C
当n=4,A——>B,A——>C,B——>C,A——B,C——>A,C——B,A——>B(至此将顶部3个盘子都移到了B上),A——>C,B——>C,B——>A,C——A,B——>C,A——B,A——>C,B——>C
当n=5,A——>C,A——>B,C——>B,A——C,B——>A,B——C,A——>C(至此将顶部3个盘子都移到了C上),A——>B,C——>B,C——>A,B——A,C——>B,A——C,A——>B,C——>B(至此将顶部4个盘子都移到了B上),A——>C(这里博主就不往下面写了,交给读者们吧,我脑子有点累。。。思路:此时B上有4个盘子,C上有一个最大的盘子,假设将C上的盘子忽略掉存在,因为它已经是最大的了,上面放任何一个盘子都不会违反规则;至此将B的情景放在上面n=4的那一步中,假设B就是A,那么继续进行,将B的最大盘子放到C上;至此再类推到第二步n=3时...)...........
当n=....
问题思考:
其实上面的问题,大家经过思考会发现,不管过程如何曲折,想要把A上n个盘子移到C上,就必须要把前n-1个盘子先放到B上,然后将最大的盘子放到C上;之后再将C上的固定了的盘子假设不存在,此刻B上的盘子当做上一步的A盘子,继续一样的思路进行(其实仔细看上面的问题手拆,会发现规律,前几步都是重复的,后几步其实只是把A换成了B或者A换成了C)。另外可能网上许多的类似关于汉诺塔的解释方法,都没有详细多少如何把n-1个盘子放到B上呢?其实给大家提供一个解决思路:想要将n-1个盘子放到B上,那就必须先将n-2个盘子移到C处,再将最大的盘子从A移到B处。其实说白了仍然是汉诺塔的递归)
代码实现(网上有很多一样的大致实现,但都是一个思路的实现,具体到函数层的实现并没有写,博主这里有时间给大家写一个做参考,暂时先放个雷同的吧):
public void hanoi(String A, String B, String C, int n) { if (n == 1) { System.out.println("这个简单,直接将" + A +"的"+n+"个盘子移动到" + C + "!"); } else { hanoi(A, C, B, n - 1); System.out.println("将" + A +"的"+n+"个盘子移动到" + C + "!"); hanoi(B, A, C, n - 1); } }
相关文章推荐
- 数据结构经典算法学习之老鼠走迷宫02
- [个人记录]小白书学习第6章数据结构基础算法竞赛入门经典第一版)
- 数据结构经典算法学习之八皇后01
- 数据结构入门学习系列-8(栈的经典算法用例)
- 数据结构经典算法学习之三色旗
- java经典算法之河内之塔(汉诺塔)
- 数据结构经典算法学习之多背包问题
- 经典高斯算法,一起学习数据结构和算法吧!
- 数据结构经典算法学习之老鼠走迷宫01
- 《Delphi 算法与数据结构》学习与感悟[8]: 单向链表的添加、删除与遍历
- 学习笔记---递归的代码,解决经典的汉诺塔问题
- 数据结构经典算法汇总___循环队列:
- 【翠字营原创】基于 cryptlib.lib 开发的几种加密解密算法经典例子 涉及: MD5 AES AES-CBC 希望对大家学习有帮助!
- 数据结构与算法 学习笔记
- 汉诺塔算法学习笔记
- 经典算法之汉诺塔
- 算法导论学习笔记-第十四章-数据结构的扩张
- 数据结构学习笔记一:简单排序与查询算法
- 【算法学习】【数据结构】treap的构建和使用
- 《Delphi 算法与数据结构》学习与感悟[10]: 双向链表