汉诺塔问题是一个古典的数学问题,也是c语言学习中一个用递归方法解题的典型实例,我们先看一下原题。

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

对于这样一个问题,我们第一印象就是十分的复杂,写出移动盘子的每一步似乎非常的困难,但我们可以利用下面的递归方法来解决。

首先分析,将n个盘子从A移动到C可以分解为三个步骤

(1)将A上的n-1个盘子借助C移动到B上;

(2)将A上剩下的一个盘子移到C上;

(3)将n-1个盘子从B移动到C上;

这对于写代码来说就变得十分简单了,但是依然很抽象,不过不要急,我们先把代码写出来再慢慢分析,

这是代码    其中hanoi函数有四个值,hano(n,A,B,C),代表着我们将盘子从A借助B移动到C上

#include <stdio.h>
void hanoi(int n,char X,char Y,char Z)//n个盘子在A上,借助B,移动到C上
{if(n==1)//如果A上只有一个盘子,直接移动到C上printf("%c-->%c\n",X,Z);else//一旦多余一个,则执行递归程序{hanoi(n-1,X,Z,Y);//将A上的n-1个盘子,借助C,移动到B上printf("%c--> %c\n",X,Z);//将A 上的最后一个盘子移动到C上hanoi(n-1,Y,X,Z);//将B上的n-1个盘子,借助A,移动到C上}
}int main()
{int n;printf("请输入盘子的总数:");scanf("%d",&n);hanoi(n,'A','B','C');return 0;
}

我第一次看到这里时,就被震撼到了,一个如此复杂的数学问题竟然可以通过短短二十几行代码来实现,可是里面对于hanio函数的反复调用却让我十分头疼,这是怎么实现的呢?

下面我们以n=3为例来详细的解释一遍,这里我们需要用到一点的概念,简单说就是每一次递归之前程序都会将现在的数据储存在栈中(从下往上存储),递归结束后会依次从上往下调出数据,之后程序就会返回到这个数据存储的地方向后继续执行,此时栈中的这一条数据也会消失。

当程序执行到第一个hanoi函数时,显然n!=1,执行else的部分,此时hanoi函数中的变量值为hanoi(3,A,B,C),在执行第8行语句之前,首先要将其存放到栈中。经过下一行的递归后,四个值变为hanoi(2,A,C,B)。

此时栈中的数据为

第一次   hanoi(2,A,C,B)
初始  hanoi(3,A,B,C)

再继续第二次运行else后的代码,得到下一组数值hanoi(1,A,B,C)并储存,

再运行时n=1,终于可以执行printf语句啦!

输出    A-->C

这时程序就要开始处理栈中的数据了,从上往下执行,将程序返回原处,赋值后执行下一行,此时函数值为hanoi(2,A,C ,B)

输出 A-->B 

继续执行时又遇到了递归程序,这时再将此时的数据储存到栈中,重新开始执行一个hanoi函数,此时hanoi(1,C,A,B)n=1,那么执行if后的语句

输出C-->B

之后返回栈中的第一条数据处,往下执行,这个时候我们发现,第一次递归的hanoi函数到此结束,程序接着处理栈中最底下的数据,hanoi(3,A,B,C)。将程序返回到这里并执行下面的语句

 输出  A-->C

下面一条又是递归啦,我们再重复上面的过程,储存数据再重新调用hanoi函数。调用后hanoi(2,B,A,C),依旧不满足n=1,再重复以上过程,得到hanoi(1,B,C,A)

此时栈中的数据为

hanoi(2,B,A,C)
hanoi(3,A,B,C)

现在n=1,输出B-->A

返回栈中第一条数据处,往后执行

输出B-->C

递归得hanoi(1,A,B,C)

再输出A-->C

此时栈中的数据为

hanoi(2,B,A,C)
hanoi(3,A,B,C)

分别对应的两个数据位置都位于hanoi函数的这个位置

在返回时,都会结束程序,所以整个递归到此结束,让我们统计一下输出的结果

输出 A-->C

输出 A-->B 

输出C-->B

输出A-->C

输出B-->A

输出B-->C

输出A-->C

这就是n=3时,整个程序的运行的结果了。

总结:汉诺塔程序本身是一个极其复杂的问题,通过递归,我们可以节省大量的代码,通过一个简短的程序来解决这个问题,但是这其中的逻辑是不可能被简化的,只是由计算机替我们执行了而已,所以彻底的了解整个程序是如何对于hanoi函数一次次的调用,虽然有一定的难度,有点难以理解,我认为是非常有必要的,这可以让我们对递归运算有一个更深刻的了解。以上是n=3的情况,较为简单,大家有能力的可以挑战一下给n赋更大的值,那样递归分析的难度也会同样暴增。

另外,如果想要统计移动次数的话,还可以增加一个全局变量来达到目的。

下面是代码

#include <stdio.h>
int i=0;//增加一个全局变量
void hanoi(int n,char X,char Y,char Z)             //n个盘子在A上,借助B,移动到C上
{i++;                  //每次调用hanoi函数,i都会+1if(n==1)                                       //如果A上只有一个盘子,直接移动到C上printf("%c-->%c\n",X,Z);else                                        //一旦多余一个,则执行递归程序{hanoi(n-1,X,Z,Y);                            //将A上的n-1个盘子,借助C,移动到B上printf("%c--> %c\n",X,Z);                        //将A 上的最后一个盘子移动到C上hanoi(n-1,Y,X,Z);                          //将B上的n-1个盘子,借助A,移动到C上}
}int main()
{int n;printf("请输入盘子的总数:");scanf("%d",&n);hanoi(n,'A','B','C');printf("一共需要移动的次数为%d",i);return 0;
}

运行截图

c语言中的汉诺塔问题详解相关推荐

  1. 汉诺塔问题详解 递归实现 C语言

    目录 一.前言 二.游戏规则 三.思路讲解 四.完整代码 五.最终结果展示 一.前言 汉诺塔:汉诺塔(Tower of Hanoi)源于印度传说中,大梵天创造世界时造了三根金钢石柱子,  其中一根柱子 ...

  2. Tower of Hanoi(汉诺塔)详解

    一个经典的汉诺塔问题,带着我自己的理解给做这个问题的友友们解决一下,包括我本人在做的时候也遇到的一些问题给大家阐述一下.话不多说,来看: 汉诺塔 问题描述: 汉诺塔(Hanoi Tower),又称河内 ...

  3. QT汉诺塔项目详解:多线程动画

    关注QT坐标,多线程动画中坐标的变化.汉诺塔都是吃要的. 我的汉诺塔新解:一种更美的描述. http://blog.csdn.net/weixin_39788534/article/details/7 ...

  4. python之汉诺塔问题详解

    #汉诺塔问题 传说古老印度在一个圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片圣庙,一块黄铜板上插着三根宝石针.印度教的主神梵 ...

  5. 算法 汉诺塔-java详解

    第一次看到这个算法时,很懵逼,是在栈那里.想了半天没想到半点跟栈有关系的解法.最后看了答案,是用的递归.但是看了答案还是很懵逼,下面就是博主自己对汉诺塔的一些了解. 有三根木桩,第一根上有n个盘子,最 ...

  6. 走进递归经典——汉诺塔问题详解

    目录 传统艺能

  7. c语言递归汉诺塔次数,c语言递归解决汉诺塔参数变化的疑惑

    c语言递归解决汉诺塔参数变化的疑惑 答案:3  信息版本:手机版 解决时间 2020-04-05 14:20 已解决 2020-04-05 10:49 #include void main() {vo ...

  8. c语言递归解决汉诺塔问题

    c语言递归解决汉诺塔问题 参考文章: (1)c语言递归解决汉诺塔问题 (2)https://www.cnblogs.com/didiaoxiaoguai/p/6686407.html 备忘一下.

  9. go语言字符串换行_Go语言中的字符串处理方法示例详解

    1 概述 字符串,string,一串固定长度的字符连接起来的字符集合.Go语言的字符串是使用UTF-8编码的.UTF-8是Unicode的实现方式之一. Go语言原生支持字符串.使用双引号(" ...

最新文章

  1. 根据PI/4 = 1 - 1/3 +1/5-1/7+1/9求圆周率
  2. 智能车竞赛技术报告 | 智能车视觉 - 西安邮电大学 - AI小布丁
  3. Linux下找出吃内存的方法总结
  4. lightroom 闪退_UP加速器闪退怎么办 UP加速器闪退解决方法
  5. 南京:第三届软博会“外包”将唱主角
  6. centos7 搭建Docker Registry
  7. 米家小白增强固件_中考体育:男1000米/女800米想拿满分,掌握呼吸法是关键
  8. 在用ganglia时出现You don‘t have permission to access ganglia on this server
  9. C语言杂记-vector 、 stack and queue
  10. [记录]Python的master-worker和epoll模式
  11. python自动写工作日志_python自动化执行重复工作
  12. GridView的DataFormatString格式化字符串
  13. wps怎么利用c语言编辑,WPS如何转换成图片?三种方法帮你实现
  14. 欧拉定理(Tetration,玲珑杯 Round#5 E lonlife 1060)
  15. 同一服务器两个端口不同的应用session覆盖解决方案
  16. Android省市县三级联动 真实项目抽出 调用只需3行代码
  17. 【plang 1.4.6】Plang高级编程语言(发布)
  18. CorelDRAW x8警告您所用的软件疑似非法盗版软件,软件功能3天内将被永久停用,解决方法教程
  19. 服务器网站绕过备案,腾讯云服务器如何利用阿里DCDN绕过备案
  20. Keras实例教程(3)

热门文章

  1. 基于MIT协议的详细介绍
  2. 中国集成电路产业人才白皮书北京发布--李武宜
  3. 3.牛顿迭代法求解方程的根
  4. klee-2.1安装(按照这个博客,闭着眼都能成功!)
  5. Qt编程中的信号和槽机制
  6. QQ2012 Beta1 (支持窗口合并、20人视频)
  7. Error: EBUSY: resource busy or locked
  8. Occlusion culling
  9. 4D毫米波雷达硬件系统架构
  10. 国产ARM核心工控主板介绍