【说明】:

  本文是左程云老师所著的《程序员面试代码指南》第一章中“用栈来实现汉诺塔问题”这一题目的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

【实现】:

  实现及测试代码:

/**文件名: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

用递归来实现汉诺塔的问题相关推荐

  1. 递归(二)-------经典递归实例(汉诺塔问题)

    2019独角兽企业重金招聘Python工程师标准>>> 上一篇文章讨论一个经典的递归实例(Fibonacy数列问题),现在来讨论一下另外一个经典的递归例子:汉诺塔问题: 问题描述:在 ...

  2. 深度理解递归,手撕经典递归问题(汉诺塔,青蛙跳台阶),保姆级教学。

    目录 序言: 一.函数递归( recursion) 二.递归的两个必要条件 三.递归小问题 (1)接受一个整型值(无符号),按照顺序打印它的每一位 (2)编写函数不允许创建临时变量,求字符串的长度(利 ...

  3. 【使用递归玩通关汉诺塔游戏】算法01-递归(斐波那契数列、汉罗塔问题)-java实现

    递归 定义:在一个方法(函数)的内部调用该方法(函数)本身的编程方式 简而言之就是 "自己调自己" 在玩游戏之前让我们先对递归有一个简单的了解吧! 5.1 递归简介 递归必须有一个 ...

  4. Java递归基础案例-汉诺塔

    汉诺塔问题 /** * Title: 汉诺塔问题 * Description:古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上. * 有一个和尚想把这64个 ...

  5. 个盘子的汉诺塔需要移动几步_坨——理解递归实现quot;汉诺塔quot;代码的关键...

    我记得,大学学C语言时,在函数递归调用那一节有个作业,就是写汉诺塔.不少同学遭遇到困难.在知乎上遇见的就有: 如何理解汉诺塔的递归?​www.zhihu.com 题主发出悲鸣:"--学C++ ...

  6. Python数据结构与算法笔记(二):递归介绍及汉诺塔问题

    递归 内容介绍 func1和func2没有结束条件. 图解func递归过程: 长框代表func3,窄框代表print.函数执行过程是从上至下. 长框代表func4,窄框代表print.函数执行过程是从 ...

  7. 递归法:汉诺塔(快速掌握)

    汉诺塔分析:转换柱子的角色,和辅助柱子 发现从递归角度:将1-N与2-N移动到B之后,在C不动的情况下,并不是同一个等价形式:经过转化之后:以下形式与原来的1-N等价 把1-N-1移动到C,N移动到B ...

  8. 汉诺塔python创新设计_递归经典案例汉诺塔 python实现

    最近在廖雪峰大神的教程学习python 学到递归的时候有个汉诺塔的练习,汉诺塔应该是学习计算机递归算法的经典入门案例了,因此本人以为能够写篇博客来表达一下本身的看法.这markdown编辑器还不怎么会 ...

  9. 数学归纳法+递归问题之汉诺塔问题

    数学归纳法: 数学归纳法有好几种形式,我们这里采用最常见的一种.其他形式,详见. PS:有时候维基百科+百度百科,对比的看,效果更好.维基更细,但百度百科可以帮助我们总结,例子也更中国思维,更容易理解 ...

  10. 递归3: 汉诺塔的递归与迭代实现

    递归实现与main(): /*------------------------------------------------------ 汉诺塔主要是有三个塔座X,Y,Z,要求将从小到大编号为 1, ...

最新文章

  1. 数字技术对就业的影响分析
  2. 全新的基于VVC思想的页面验证js框架vtor
  3. pLSA概率潜在语义分析
  4. java 正则 实例_Java正则表达式实例详解
  5. 简历的正确发音和习惯用法
  6. 深度学习修炼(一)——从机器学习转向深度学习
  7. 【转】!!c#文件系统操作类继承关系图
  8. java json和对象互相装换
  9. MySQL无法远程连接解决方案
  10. Bootstrap3 滚动监听插件的事件
  11. 【爬虫剑谱】三卷3章 拾遗篇-有关于bs4库中的BeautifulSoup模块使用小结
  12. 关于 Google 发布的 JS 代码规范
  13. 在nhibernate 1.2 中使用sqlite时应注意sqlite的ado.net的提供者 .
  14. Charles使用备注[1]
  15. ( # #@ ## 在define中的应用)或( 连接两个字符串或者两个数字、强制转化成单引号、强制转化成双引号 )附加字符串强制转化成数字...
  16. matlab计算abc三相短路电流_不用到处问别人了,关于变压器的相关计算公式,都在这里!收藏好...
  17. 谷歌浏览器离线更换皮肤-安装谷歌浏览器插件与问题解决
  18. RK3399 opencv rtsp流报错drm prime is not supported as input pixel format
  19. 手机远程计算机桌面,远程桌面预览Windows10,您可以远程通过手机控制电脑
  20. android蓝牙传输文件到mysql_安卓上的蓝牙数据传输

热门文章

  1. Python中执行系统命令常见的几种方法
  2. 七张王牌助你做人做事顺遂成功
  3. 正则表达式替换文本前n字符
  4. netfilter源码学习
  5. 谈谈Linux的栈回溯与妙用
  6. sofia-sip帮助文档
  7. H.264码流解析 一个SPS的nalu及获取视频的分辨率
  8. 解决android Studio 安装完运行提示failed to find build tools revision 24.0.2
  9. B - I Hate It(单点更新)(区间求最大值)
  10. linux抓包命令不用root用户,linux中非root用户使用wireshark进行抓包