汉诺塔的图解递归算法
一.起源:
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
二.抽象为数学问题:
如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数
解:(1)n == 1
第1次 1号盘 A---->C sum = 1 次
(2) n == 2
第1次 1号盘 A---->B
第2次 2号盘 A---->C
第3次 1号盘 B---->C sum = 3 次
(3)n == 3
第1次 1号盘 A---->C
第2次 2号盘 A---->B
第3次 1号盘 C---->B
第4次 3号盘 A---->C
第5次 1号盘 B---->A
第6次 2号盘 B---->C
第7次 1号盘 A---->C sum = 7 次
不难发现规律:1个圆盘的次数 2的1次方减1
2个圆盘的次数 2的2次方减1
3个圆盘的次数 2的3次方减1
。 。 。 。 。
n个圆盘的次数 2的n次方减1
故:移动次数为:2^n - 1
三.算法分析(递归算法):
我们在利用计算机求汉诺塔问题时,必不可少的一步是对整个实现求解进行算法分析。到目前为止,求解汉诺塔问题最简单的算法还是同过递归来求。
实现这个算法可以简单分为三个步骤:
(1) 把n-1个盘子由A 移到 B;
(2) 把第n个盘子由 A移到 C;
(3) 把n-1个盘子由B 移到 C;
从这里入手,在加上上面数学问题解法的分析,我们不难发现,移到的步数必定为奇数步:
(1)中间的一步是把最大的一个盘子由A移到C上去;
(2)中间一步之上可以看成把A上n-1个盘子通过借助辅助塔(C塔)移到了B上,
(3)中间一步之下可以看成把B上n-1个盘子通过借助辅助塔(A塔)移到了C上;
public class Hanoilmpl {public static void hanoi(int n, char A, char B, char C) {if (n == 1) {move(A, C);} else {hanoi(n - 1, A, C, B);//将n-1个盘子由A经过C移动到Bmove(A, C); //执行最大盘子n移动hanoi(n - 1, B, A, C);//剩下的n-1盘子,由B经过A移动到C}}private static void move(char A, char C) {//执行最大盘子n的从A-C的移动System.out.println("move:" + A + "--->" + C);}public static void main(String[] args) {System.out.println("移动汉诺塔的步骤:");hanoi(3, 'a', 'b', 'c');}
}
四.可怕的汉诺塔
汉诺塔是一个发源于印度的益智游戏,也叫河内塔。相传它源于印度神话中的大梵天创造的三个金刚柱,一根柱子上叠着上下从小到大64个黄金圆盘。大梵天命令婆罗门将这些圆盘按从小到大的顺序移动到另一根柱子上,其中大圆盘不能放在小圆盘上面。当这64个圆盘移动完的时候,世界就将毁灭。
汉诺塔问题源于印度神话
那么好多人会问64个圆盘移动到底会花多少时间?那么古代印度距离现在已经很远,这64个圆盘还没移动完么?我们来通过计算来看看要完成这个任务到底要多少时间?
我们首先利用数学上的数列知识来看看F(n=1)=1,F(n=2)=3,F(n=3)=7,F(n=4)=15……F(n)=2F(n-1)+1;
我们使用数学归纳法可以得出通项式:F(n)=2^n-1。当n为64时F(n=64)=18446744073709551615。
我们假设移动一次圆盘为一秒,那么一年为31536000秒。那么18446744073709551615/31536000约等于584942417355天,换算成年为5845.54亿年。
目前太阳寿命约为50亿年,太阳的完整寿命大约100亿年。所以我们整个人类文明都等不到移动完整圆盘的那一天。
20次以内秒级别的,没问题,30以上就费劲了!
五.汉诺塔问题拓展
有一个int数组arr其中只含有1、2和3,分别代表所有圆盘目前的状态,1代表左柱,2代表中柱,3代表右柱,arr[i]的值代表第i+1个圆盘的位置。比如,arr=[3,3,2,1],代表第1个圆盘在右柱上、第2个圆盘在右柱上、第3个圆盘在中柱上、第4个圆盘在左柱上。如果arr代表的状态是最优移动轨迹过程中出现的状态,返回arr这种状态是最优移动轨迹中的第几个状态。如果arr代表的状态不是最优移动轨迹过程中出现的状态,则返回-1。
给定一个int数组arr及数组的大小n,含义如题所述,请返回一个int,代表所求的结果。
测试样例:[3,3]
返回:3
解析:
1.如果当前盘子在中间,不是最优解(直观观察);
2.如果当前盘子在最右边,说明数组已经完成了Hanoi的前两步,第一步将前n-1移动到中间步数为2^(n-1)-1,然后最后一个n移动到右边步数为1,总共为2^(n-1);
此时只需要递归判断前n-1个数组的移动次数,并且添加进来;
3.如果当前盘子最左边,说明对第n盘子没有进行任何操作(如果是最优解),只需要递归求解前n-1个盘子的操作次数
具体参见实现代码:
public int chkStep(int[] arr, int n) {if (arr == null || arr.length < 1 || arr.length != n) {return -1;}return checkstep(arr, n - 1, 1, 2, 3);}private int checkstep(int[] arr, int cur, int left, int mid, int right) {if (cur == -1) {// 所有盘子递归完毕return 0;}if (arr[cur] == mid) {// 在中间return -1;} else if (arr[cur] == left) {// 在左边return checkstep(arr, cur - 1, left, right, mid);} else {// 在右边int tmp = checkstep(arr, cur - 1, mid, left, right);if (tmp == -1) { // 如果cur-1个盘子不是最优解return -1;}return (1 << cur) + tmp;}}
参考链接:1.http://www.cnblogs.com/dmego/p/5965835.html
2.https://blog.csdn.net/xb2355404/article/details/79144451
汉诺塔的图解递归算法相关推荐
- python汉诺塔递归算法流程图_python实现汉诺塔的图解递归算法
一.起源: 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小 ...
- 汉诺塔问题的递归算法和非递归算法分析
汉诺塔问题的递归算法和非递归算法分析 不想看文字的可以在B站看详细的讲解,点击蓝字->汉诺塔问题的递归和非递归算法 问题描述 相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏.该游戏是 ...
- 【头歌】汉诺塔(Hanoi)的递归算法
任务描述 本关任务:汉诺塔(Hanoi)的递归算法. 相关知识 相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏.该游戏是在一块铜板装置上,有三根杆(编号A.B.C),在A杆自下而上.由大到 ...
- python汉诺塔递归算法_Python文摘:汉诺塔问题与递归算法
历史传说: 在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑夜 ...
- Python文摘:汉诺塔问题与递归算法
历史传说: 在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑夜 ...
- 汉诺塔(图解演算+推导+Python实现)
汉诺塔 文章目录 汉诺塔 前言 时间线 故事背景 问题延申:经典汉诺塔 逻辑演算 代码处理 对象定义 动作定义 递归 计数 代码实现 总结 前言 关于汉诺塔的记忆很早就有了,无论还是益智玩具,还是电影 ...
- 汉诺塔问题(递归算法思想)
⛩️博主主页:@威化小餅干
- python面向过程实践汉诺塔_递归汉诺塔-和递归汉诺塔相关的内容-阿里云开发者社区...
多柱汉诺塔最优算法设计探究 多柱汉诺塔最优算法设计探究 引言 汉诺塔算法一直是算法设计科目的最具代表性的研究问题,本文关注于如何设计多柱汉诺塔最优算法的探究.最简单的汉诺塔是三个柱子(A.B.C),因 ...
- C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)
本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...
- python汉诺塔_汉诺塔递归算法/搬金盘的婆罗门 - Python实现
汉诺塔递归算法/搬金盘的婆罗门 - Python实现 版权声明 本文节选自作者本人的图书<Python编程基础及应用>,高等教育出版社.本文可以在互联网上自由转载,但必须:注明出处(作者: ...
最新文章
- 字符串处理函数C语言实现(一)
- 数据中心行业在能源转型中将发挥重要作用
- JavaScript栈的实现
- asp.net 时间显示格式
- java ajax jquery分页插件_jquery ajax分页插件的简单实现
- 和谐社区,和谐技术:微软的宠儿们,为什么富人的孩子就不能早当家?
- Centos6 使用yum快速搭建LAMP环境
- html ready 调用函数,Chrome和JQuery问题 - $(document).ready(function(){});在页面加载之前调用...
- 记一次java-selenium自动抢红包最简单案例1
- 80后,规划好你的职业道路!
- pentaho mysql_pentaho5.0.1,mysql5 配置,安装
- bootstrap制作一个优美的导航栏
- linux操作系统是著名的分布式系统,紫光展锐操作系统生态覆盖 Android、Linux、RTOS,面向分布式、智能化...
- MCU芯片设计和软件开发
- java mysql 语句中 大于 小于 等于 的写法
- JavaWeb之jsp
- Mac OS安装NS 3
- 4.unity UI ScrollRect 无限滚动条(最详细)
- Spring Boot —— Mybatis-Plus(小试小刀)
- 【Rhapsody学习笔记(一)】OrionHealth-Rhapsody的组成及常用过滤器