学习笔记(菜鸟日志)-"汉诺塔"的递归过程

记得大一上C语言课程的时候我还刚刚会用迅雷下载电影,听不懂,也没认真听过,匆匆几个星期上完了考试。关于“汉诺塔”这样的字眼,也是仅仅记得是在那个书里面出现过而已。最近偶然拿起C语言的书,再次看到了“汉诺塔”递归算法的例子,转好几圈,终于搞明白了。现在花点时间重新这里下思路,一则方便自己以后回忆,二则希望能给和我一样菜的新手们提供参考,三则希望有高人出现对文中不足的地方加以斧正!

   关于“汉诺塔”这个古老的益智游戏如果不清楚的,到百度百科一下!

 

 

为了方便理解,这里首先创造三个概念:源,踏板,目标。

如果任务是:将A上的圆盘移动至C,我们称A为源,B为踏板,C为目标。

思路:1 要是源上只有一个圆盘,只直接将圆盘移动至目标。(无需借助踏板过渡)

2 要是源上有n(n>1)个圆盘,则分为下面三个步骤完成。(借助踏板)

A先将前n-1个移动到踏板上(由上至下的顺序) 先移动到踏板上。(任务细分,重复1,2两个步骤)

B 再将最后(第n个)一个移动至目标。

C 最后在将踏板上的全部移动至目标。(任务细分,重复1,2两个步骤)

就上图一我们按照上面的思路递归一下整个过程:

第一层:进栈

 任务:A (源) 移动3  C(目标) ,n=3>1,所以借助B(踏板),先将 前两个先

 移动至B,再将最后一个移动至C,最后将踏板上的移动至C。

第二层:进栈

任务:A (源)移动2  B(目标) ,n=2>1,所以借助C(踏板),先将前 一个先

 移动C,再将当前任务的最后一个移动至B,最后将踏板C上的移动至B。

第三层:进栈

任务:A (源) 移动1  C(目标) ,n=1=1,直接将A上最上面一个移动至C;

 

 

出栈。

回溯到第二层:

将当前任务的最后一个移动至B。                                             

         
     
   

 

 踏板C上的移动至目标B

 

 

 出栈。

 

回溯到第一层:

  现在已经完成了将A上的上面两个移动至踏板B上,现在还剩下两个步骤:

将A上的一个移动到C上,将踏板B上的两个移动到C上。

1将A上的移动到C上。

 

 

2 将B的两个移动到C 上。分两步进行:

第二层:进栈

借助A为踏板,先将B得上一个移动到A上。

 

 

将B上的最底下一个移动至目标C

 

 

踏板A上的移动至目标C 
 

 

 

出栈

出栈

自此,整个任务完成!

 

C/C++代码:
#include "stdio.h"

int main()

{

 void hanoi(int n,char origin,char bridge,char destination);         // 对hanoi函数的声明

  intm;

 printf("input the number of diskes:");

 scanf("%d",&m);

 printf("The step to move %d diskes:\n",m);

 hanoi(m,'A','B','C');

 return 0;

}

 

void hanoi(int n,char origin,charbridge,char destination)          // 定义hanoi函数 

   // 将n个盘从origin座借助bridge座,移到 destination座

 {

 void move(char x,char y);       //对move函数的声明

 if(n==1)

    move(origin,destination);

 else

    {

     hanoi(n-1,origin,destination,bridge);

    move(origin,destination);

    hanoi(n-1,bridge,origin,destination);

    }

 }

 

 voidmove(char x,char y)           //  定义move函数

 {

  printf("%c-->%c\n",x,y);

 }

 

 

 

 

时间: 2024-09-21 18:31:20

学习笔记(菜鸟日志)-"汉诺塔"的递归过程的相关文章

c语言汉诺塔-汉诺塔可以用递归吗 不找规律的话

问题描述 汉诺塔可以用递归吗 不找规律的话 汉诺塔可以用递归吗 不找规律的话 求大神指点 递归应该怎么用才能解决汉诺塔 谢谢了 解决方案 汉诺塔本来就应该用递归,不用递归反倒麻烦,需要用堆栈模拟.http://blog.csdn.net/kkkkkxiaofei/article/details/8333644 解决方案二: #include<stdio.h> void move(int n,char a,char b,char c) { if(n==1) printf("t%c-&g

初学者c语言动态汉诺塔帮忙注释

问题描述 初学者c语言动态汉诺塔帮忙注释 #include #include #define N 1000 void gotoxy(int x, int y); // 声明gotoxy函数 void colorxy(int x, int y); //声明colorxy函数 void hanoi(int n,char a,char b,char c); //声明hanoi函数 void move(int n,char a,char b); //声明move函数 void Print(); //声明

【Python学习】Python解决汉诺塔问题

参考文章:http://www.cnblogs.com/dmego/p/5965835.html 一句话:学程序不是目的,理解就好:写代码也不是必然,省事最好:拿也好,查也好,解决问题就好! 信息时代不用信息就是罪过,直接抄不加理解与应用,就不是自己的,下次遇到还是不会,或许其中的某一个细节就能够用于各个问题的解决,共勉 学习一个东西总会遇到一些经典的问题,学习Python第二天尝试看一下汉诺塔问题,还是百度,看看解题思路,纯粹是重温初中课堂,越活越回去了  汉诺塔的图解递归算法 一.起源: 汉

算法-汉诺塔是怎么思考出来的

问题描述 汉诺塔是怎么思考出来的 本人菜鸟,看到这个算法的时候觉得好巧妙,但是自己怎么也想不出来啊... 解决方案 所谓递归,其实人类是做不到的,因为递归嵌套多了,人就乱了,有点像是盗梦空间里的深层梦境limbo,到那就几乎回不到现实了. 但是计算机不像人类想法那么多,尤其是基于过程的设计,你教我怎么走我就怎么走,不会混乱,但是你得给我定个边界条件,要不我还是回不来. 汉诺塔的确是一个经典的递归问题,而人类做的最伟大的一步在于,把f(n)的问题转化为f(n-1),推本溯源,总要找到一个origi

python实现汉诺塔方法汇总_python

学习python遇到的第一个问题:汉诺塔问题的实现.首先是不知道什么是汉诺塔问题,然后是不知道怎么实现.于是百度了下,结果如下: 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘 方法一: def move(n,a,b,c) # n=2 if n==1 :

c#汉诺塔的递归算法与解析_C#教程

从左到右 A  B  C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱, 期间只有一个原则: 大盘子只能在小盘子的下面. 如果有3个盘子, 大中小号, 越小的越在上面, 从上面给盘子按顺序编号 1(小),2(中),3(大), 后面的原理解析引用这里的编号. 小时候玩过这个游戏, 基本上玩到第7个,第8个就很没有耐心玩了,并且操作的动作都几乎相同觉得无聊.  后来学习编程, 认识到递归, 用递归解决汉诺塔的算法也是我除了简单的排序算法后学习到的第一种算法. 至于递归,简单来说

C语言实现汉诺塔游戏_C 语言

操作就是:A B 号码A的塔顶一层放在号码B的塔顶.如1(空格) 3 回车. 话说有人能把我这C的代码添加到QT界面框架上去么?  代码写的不好 ,维护性不够,只能玩8层的,写完以后发现很难拓展,软件工程,设计模式有待提高.... 里面提示输入等级的装B用了,没有实现,大家随便输入个个位数就可以玩了. stackfunc.c #include"STACK.h" #include<stdio.h> extern ceng CENG[SIZE]; //数据入栈 void pus

C语言递归实现汉诺塔算法

汉诺塔的递归实现算法,将A中的圆盘借助B圆盘完全移动到C圆盘上, 每次只能移动一个圆盘,并且每次移动时大盘不能放在小盘上面 递归函数的伪算法为如下: if(n == 1) 直接将A柱子上的圆盘从A移动到C else 先将A柱子上的n-1个圆盘借助C柱子移动到B柱子上 直接将A柱子上的第n个圆盘移动到C柱子上 最后将B柱子上的n-1个圆盘借助A柱子移动到C柱子上 该递归算法的时间复杂度为O(2的n次方),当有n个圆盘时,需要移动圆盘2的n次方-1次 操作系统:ubuntu 编译软件:gcc 结果截

汉诺塔游戏的设计

汉诺塔问题是最经典的递归问题,笔者就该问题设计了这个游戏,由用户交互 游戏和自动演示两部分组成,支持撤销功能.选关.自动完成等功能. 首先 建立了类CMap,该类主要实现用户每一步的操作和画图显示功能,记录的时候只 须记录每组盘子的个数和盘子的矩形.代码和注释如下: //记录 每一步的盘子的情况 class CMap { public: //每组 盘子的个数 int iCount[3]; //3组盘子里面,每个盘子的位 置,用矩形表示 RECT *Rect[3]; //构造函数 CMap() {