用递归来实现汉诺塔的问题
【说明】:
本文是左程云老师所著的《程序员面试代码指南》第一章中“用栈来实现汉诺塔问题”这一题目的C++递归方法复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
题目再重述一遍:
汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而必须经过中间。求当有N层塔的时候,打印最优移动过程和最优移动总步数。
例如,当塔为两层时,最上层的塔记录为1,最下层的塔记录为2,则打印:
move 1 from left to mid
move 1 from mid to right
move 2 from left to mid
move 1 from right to mid
move 1 from mid to left
move 2 from mid to right
move 1 from left to mid
move 1 from mid to right
It will move 8 steps.
【思路】:
递归的终止条件:汉诺塔只剩一层的时候。
对于普通的汉诺塔问题来说,递归的思路为:将n-1个盘子从A移到B,把最下面个移到C,然后把N-2个从B移到A,第N-1个移到C,如此继续下去。
对于本文所述的汉诺塔问题,递归思路差不多,读者可参考左老师的书,或者直接从我写的代码猜测。
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现】:
实现及测试代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
/**文件名:limithannoi_recursion.cpp*作者:*摘要:使用递归的方法实现增加限制后的汉诺塔问题*/#include <iostream> #include <string>using namespace std;int hanoiRec(int layer,string src,string dst) {if(1 > layer)return 0;if(1 == layer) //只有一层时(递归的退出检测) {if("mid" == src || "mid" == dst) //源端或目的端为中间的情况 {cout << "move 1 form " << src << " to " << dst << endl;return 1;}else //源端或目的端为非中间的情况(左/右) {cout << "move 1 form " << src << " to mid" << endl;cout << "move 1 form mid to " << dst << endl;return 2; }}//有多层的情况if("mid" == src || "mid" == dst) //源端或目的端为mid的情况(普通的汉诺塔问题) {//获得辅助端(左/右)string aux = ("left" == src || "left" == dst) ? "right" : "left"; //第一步,将1~layer-1层从源端移动到辅助端int step1 = hanoiRec(layer-1,src,aux);//第二步,将第layer层移动到目的端int step2 = 1;cout << "move " << layer << " from " << src << " to " << aux << endl;//第三步,将1~layer-1层从辅助端移动到目的端int step3 = hanoiRec(layer-1,aux,dst);return step1 + step2 + step3;}else //源端和目的端为非mid的情况 {//第一步,将1~layer-1层从源端移动到目的端int step1 = hanoiRec(layer-1,src,dst);//第二步,将第layer层从源端移动到mid端(即mid端为辅助端)int step2 = 1;cout << "move " << layer << " from " << src << " to mid" << endl;//第三步,将1~layer-1层从目的端移动到源端int step3 = hanoiRec(layer-1,dst,src);//第四步,将第layer层从mid端移动到目的端int step4 = 1;cout << "move " << layer << " from mid to " << dst << endl;//第五步,将1~layer-1层从源端移动到目的端int step5 = hanoiRec(layer-1,src,dst);return step1 + step2 + step3 +step4 + step5;} }int main() {int step = hanoiRec(2,"left","right");cout << "It will move " << step << " steps." << endl;return 0; }
View Code
【一点想说的】:
陈丹青先生在优酷中有一个名为《局部》的艺术节目,在第一季(目前只有一季)第四集《初习的作品》中,陈丹青先生提到这么一个事情:有一位朋友去他家做客时,就挨个的欣赏挂在他家墙上的画,每一幅停留的时间都不长,知道走到梵高的这一个小的未完成的人物画像前,陈丹青先生的朋友驻足良久,说到:“我操,真他妈好看!”。
我想说的是:“我操,递归这种思想真他妈神奇。”
^_^ ^_^ ^_^
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。
转载于:https://www.cnblogs.com/PrimeLife/p/5331802.html
用递归来实现汉诺塔的问题相关推荐
- 递归(二)-------经典递归实例(汉诺塔问题)
2019独角兽企业重金招聘Python工程师标准>>> 上一篇文章讨论一个经典的递归实例(Fibonacy数列问题),现在来讨论一下另外一个经典的递归例子:汉诺塔问题: 问题描述:在 ...
- 深度理解递归,手撕经典递归问题(汉诺塔,青蛙跳台阶),保姆级教学。
目录 序言: 一.函数递归( recursion) 二.递归的两个必要条件 三.递归小问题 (1)接受一个整型值(无符号),按照顺序打印它的每一位 (2)编写函数不允许创建临时变量,求字符串的长度(利 ...
- 【使用递归玩通关汉诺塔游戏】算法01-递归(斐波那契数列、汉罗塔问题)-java实现
递归 定义:在一个方法(函数)的内部调用该方法(函数)本身的编程方式 简而言之就是 "自己调自己" 在玩游戏之前让我们先对递归有一个简单的了解吧! 5.1 递归简介 递归必须有一个 ...
- Java递归基础案例-汉诺塔
汉诺塔问题 /** * Title: 汉诺塔问题 * Description:古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上. * 有一个和尚想把这64个 ...
- 个盘子的汉诺塔需要移动几步_坨——理解递归实现quot;汉诺塔quot;代码的关键...
我记得,大学学C语言时,在函数递归调用那一节有个作业,就是写汉诺塔.不少同学遭遇到困难.在知乎上遇见的就有: 如何理解汉诺塔的递归?www.zhihu.com 题主发出悲鸣:"--学C++ ...
- Python数据结构与算法笔记(二):递归介绍及汉诺塔问题
递归 内容介绍 func1和func2没有结束条件. 图解func递归过程: 长框代表func3,窄框代表print.函数执行过程是从上至下. 长框代表func4,窄框代表print.函数执行过程是从 ...
- 递归法:汉诺塔(快速掌握)
汉诺塔分析:转换柱子的角色,和辅助柱子 发现从递归角度:将1-N与2-N移动到B之后,在C不动的情况下,并不是同一个等价形式:经过转化之后:以下形式与原来的1-N等价 把1-N-1移动到C,N移动到B ...
- 汉诺塔python创新设计_递归经典案例汉诺塔 python实现
最近在廖雪峰大神的教程学习python 学到递归的时候有个汉诺塔的练习,汉诺塔应该是学习计算机递归算法的经典入门案例了,因此本人以为能够写篇博客来表达一下本身的看法.这markdown编辑器还不怎么会 ...
- 数学归纳法+递归问题之汉诺塔问题
数学归纳法: 数学归纳法有好几种形式,我们这里采用最常见的一种.其他形式,详见. PS:有时候维基百科+百度百科,对比的看,效果更好.维基更细,但百度百科可以帮助我们总结,例子也更中国思维,更容易理解 ...
- 递归3: 汉诺塔的递归与迭代实现
递归实现与main(): /*------------------------------------------------------ 汉诺塔主要是有三个塔座X,Y,Z,要求将从小到大编号为 1, ...
最新文章
- 数字技术对就业的影响分析
- 全新的基于VVC思想的页面验证js框架vtor
- pLSA概率潜在语义分析
- java 正则 实例_Java正则表达式实例详解
- 简历的正确发音和习惯用法
- 深度学习修炼(一)——从机器学习转向深度学习
- 【转】!!c#文件系统操作类继承关系图
- java json和对象互相装换
- MySQL无法远程连接解决方案
- Bootstrap3 滚动监听插件的事件
- 【爬虫剑谱】三卷3章 拾遗篇-有关于bs4库中的BeautifulSoup模块使用小结
- 关于 Google 发布的 JS 代码规范
- 在nhibernate 1.2 中使用sqlite时应注意sqlite的ado.net的提供者 .
- Charles使用备注[1]
- ( # #@ ## 在define中的应用)或( 连接两个字符串或者两个数字、强制转化成单引号、强制转化成双引号 )附加字符串强制转化成数字...
- matlab计算abc三相短路电流_不用到处问别人了,关于变压器的相关计算公式,都在这里!收藏好...
- 谷歌浏览器离线更换皮肤-安装谷歌浏览器插件与问题解决
- RK3399 opencv rtsp流报错drm prime is not supported as input pixel format
- 手机远程计算机桌面,远程桌面预览Windows10,您可以远程通过手机控制电脑
- android蓝牙传输文件到mysql_安卓上的蓝牙数据传输