汉诺塔是很简单也很经典的算法之一。
汉诺塔是根据一个传说形成的数学问题:
有三根杆子A,B,C 。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
* 1 每次只能移动一个圆盘;
* 2 大盘不能叠在小盘上面。

提示:可将圆盘临时置于B杆,也可以将A杆移除的圆盘重新移动回A杆,但都必须遵循上述两条规则。
问:如何移?最少要移动多少次?

传说

最早发明这个问题的人是法国数学家爱德华*卢卡斯。
传说印度某间寺院有三根柱子,上串64个金盘。寺院里的僧侣依照一个古老的预言,以上述规则移动这些盘子;预言说当这些盘子移动完毕,世界就会灭亡。这个传说叫做梵天寺之塔问题(Tower of Brahma puzzle)。但不知道是卢卡斯自创的这个传说,还是他受他人启发。
若传说属实,僧侣们需要264− 1步才能完成这个任务;若他们每秒可完成一个盘子的移动,就需要5849亿年才能完成。整个宇宙现在也不过137亿年。
这个传说有若干变体:寺院换成修道院、僧侣换成修士等等。寺院的地点众说纷纭,其中一说是位于越南的河内,所以被命名为“河内塔”。另外亦有“金盘是创世时所造”、“僧侣们每天移动一盘”之类的背景设定。
佛教中确实有“浮屠”(塔)这种建筑;有些浮屠亦遵守上述规则而建。“河内塔”一名可能是由中南半岛在殖民时期传入欧洲的。

解答

如取N=64,最少需移动264− 1次。即如果一秒钟能移动一块圆盘,仍将需5849.42亿年。目前按照宇宙大爆炸理论的推测,宇宙的年龄仅为137亿年。
在真实玩具中,一般N=8;最少需移动255次。如果N=10,最少需移动1023次。如果N=15,最少需移动32767次;这就是说,如果一个人从3岁到99岁,每天移动一块圆盘,他最多仅能移动15块。如果N=20,最少需移动1048575次,即超过了一百万次。

解法

解法的基本思想是递归。假设有A、B、C 三个塔,A塔有N块盘,目标是把这些盘全部移动到C塔。那么先把塔顶部的N-1块盘移动到B塔,再把A塔剩下的大盘移动到C,最后把B塔的N-1块盘移动到C。
每次移动多于一块盘时,则再次使用上述算法来移动。

怎么来理解呢?
我们可以倒着理解,要将A塔上的所有圆盘移动到C塔,且所有圆盘是下大上小。那么必定有一个过程是最大的圆盘(也就是第N个圆盘)从A移动到C。那么必须保证上面的N-1个圆盘全在B塔,且圆盘满足上面小,下面大。当第N个圆盘从A移动到C之后,又得把N-1个圆盘从B塔移动到C塔,这样工作就完成了。
但是怎么把A塔上的N-1个圆盘移动到B塔呢?
这里需要一点想象力,可以想象成只有N-1个圆盘,从A塔移动到B塔(此时的B塔其实就相当于上面的C塔),我们称A塔为A1塔,B塔为C1塔,C塔为B1塔,那么问题就变成了如何将N-1个盘从A1塔移动到C1塔?
同样的需要将上面的N-2个圆盘从A1塔移动到B1塔,然后将第N-1个圆盘从A1塔移动到C1塔,然后再将B1塔上的N-2个圆盘移动到C1塔。
同理,递推第N-2个塔…..。

将 B塔上的 N-1个盘,移动到C塔的过程与上面原理一样。

递归解

以Objective-C语言实现:

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view from its nib.int n = 9;[self hannoi:n from:@"A" buffer:@"B" to:@"C"];NSLog(@"一共 %d 步",count);
}- (void)hannoi:(int)n from:(NSString *)from buffer:(NSString *)buffer to:(NSString *)to
{if (n == 1) {NSLog(@"Move disk %d from %@ to %@", n, from, to);} else {[self hannoi:n-1 from:from buffer:to to:buffer];NSLog(@"Move disk %d from %@ to %@", n, from, to);[self hannoi:n-1 from:buffer buffer:from to:to];}
}console : 一共 511 步

以C++语言实现:

using namespace std;
#include <iostream>
#include <cstdio>void hannoi (int n, char from, char buffer, char to)
{if (n == 1) {cout << "Move disk " << n << " from " << from << " to " << to << endl;} else {hannoi (n-1, from, to, buffer);cout << "Move disk " << n << " from " << from << " to " << to << endl;hannoi (n-1, buffer, from, to);}
}int main()
{int n;cin >> n;hannoi (n, 'A', 'B', 'C');return 0;
}

通过以上递归过程可知hannoi(n) = 2 * hannoi(n-1) + 1 ,hannoi(n) = 2n-1 + 2n-2 + 2n-3+ …… + 22 + 2 +1。
对等比数列求和得出hannoi(n) = 2n -1。

算法之路(四)----汉诺塔(又称河内之塔)相关推荐

  1. “三色河内塔”算法(三色汉诺塔)

    问题引入 "三色河内塔"由"河内之塔"的规则衍生而来(点击查看),区别在于三色河内塔的目的是将图1所示的圆盘位置,移动成为图2所示的圆盘位置."三色河 ...

  2. “双色河内塔”算法(双色汉诺塔)

    问题引入 "双色河内塔"由"河内之塔"的规则衍生而来(点击查看),区别在于双色河内塔的目的是将图1所示的圆盘位置,移动成为图2所示的圆盘位置. 图1 图2 问题 ...

  3. 算法(9)汉诺塔图解及其代码实现

    写在前面: 我是「扬帆向海」,这个昵称来源于我的名字以及女朋友的名字.我热爱技术.热爱开源.热爱编程.技术是开源的.知识是共享的. 这博客是对自己学习的一点点总结及记录,如果您对 Java.算法 感兴 ...

  4. 算法第一期:汉诺塔问题(python通俗易懂版)

    问题描述: 汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面 ...

  5. python实现汉诺塔递归经典算法_Python递归实现汉诺塔算法示例

    本文实例讲述了Python递归实现汉诺塔算法.分享给大家供大家参考,具体如下: 最近面试题,面试官让我5分钟实现汉诺塔算法(已然忘记汉诺塔是啥). 痛定思痛,回来查了一下汉诺塔的题目和算法.题干与实现 ...

  6. 算法:递归(汉诺塔)

    要点:函数定义中调用函数自身的方式形成递归. 递归的定义:递归,就是在运行的过程中调用自己. 数学上有个经典的递归例子叫阶乘,阶乘通常定义如下: n! = n(n-1)(n-2)-(1) 为了算出这个 ...

  7. 算法:递归启蒙-汉诺塔

    基本所有的讲递归的书和视频都会以汉诺塔作为开始,因为它足够经典 汉诺塔问题要求整个挪动的过程中都符合小压大的原则,就是如果同一个柱子上有超过1个的话,那必须下面是最大的,上面依次变小,不能出现大盘压小 ...

  8. 汉诺塔(河内之塔)相关题目

    1. 标准汉诺塔 题目: 汉诺塔由三根柱子(分别用A.B.C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的 ...

  9. 证明并推导汉诺塔(河内之塔)问题公式

    本文链接:http://www.cnblogs.com/xxNote/p/3965739.html   第一次遇到汉诺塔问题时我瞬间就被搞蒙了之后果断扔下不管了,今天再次遇到这个问题被搞蒙again, ...

最新文章

  1. 笨方法python3_“笨方法”学Python3,习题 41 。
  2. webpack.DefinePlugin使用介绍
  3. 动态让控件超出屏幕_JAVA浏览器控件JxBrowser v7.5上线!更轻松处理Dynamic Favicons...
  4. js动态获取时间的方式
  5. Java 截取反斜杠--java使用split拆分特殊字符
  6. Java高级:mysqllimit两个参数
  7. 深入研究java.lang.Runtime类【转】
  8. C#与NET实战 第5章 进程、线程与同步 节选
  9. zTree加Layui 实现增加和删除,有子节点不允许删除
  10. android-- apktool反编译工具使用详解
  11. sql server下载教程
  12. 竞价推广账户日常优化需要注意十大要点
  13. Android网络视频播放器DEMO
  14. 计算机辅助设计与制造考试重点,2016计算机辅助设计与制造复习内容
  15. JAVA 实现《黄金矿工》游戏
  16. ES 矩阵查询(Adjacency matrix aggregation)
  17. java float 判断整数_判断一个数是否是整数
  18. 软考是什么?考哪个科目容易过?
  19. (Leiden)From Louvain to Leiden:guaranteeing well-connected communities
  20. pytorch之迁移学习

热门文章

  1. Lab: Exploiting XXE using external entities to retrieve files:利用外部实体利用 XXE 来检索文件...
  2. 竞拍H5,源码,玉石、字画等转拍程序
  3. 如何用命令行进入MySQL数据库?
  4. 计算机操作系统进程同步实验报告,操作系统进程同步和互斥的实验报告
  5. uniapp实现图片上传和回响配合uview组件
  6. 详解计算机中的字、字节(Byte)、比特(bit)及它们之间的关系
  7. MATLAB函数参数的传递
  8. 百度推出的echarts,制表折线图柱状图饼图等的超级工具
  9. 读沈向阳博士《You are how you read》有感
  10. Ubuntu系统装了搜狗输入法,但还是不能在QT中输入中文的解决方法