C语言汉诺塔递归算法实现
这是个目录
一、什么是递归函数
函数调用自己的行为就是递归,递归必须要有终止条件,不然它会无限递归。
1.先看一下一个递归的例子
此程序的factorial函数参数从大到小地一级一级地调用自己,直到参数为1,然后函数就开始返回一级一级的从小到大地累乘,然后就计算出number的阶乘了。
#include<stdio.h>
#include<stdlib.h>
int factorial(int num);
int main(void)
{
int number=0;
int result=0;
printf("Calculating factorial: ");
scanf("%d",&number);
result=factorial(number);
printf("The result is %d\n",result);
system("pause");
return 0;
}
int factorial(int num)
{
if(num == 1)
return 1;
else
return num*factorial(num-1);
}
2.递归的基本原理
以下是《C Prinmer Plus》对于递归的描述:
- 每级调用都有自己的变量
- 每次函数调用都会返回一次
- 递归函数中位于递归调用之前的语句,均按被调函数的顺序执行。
- 递归函数中位于递归调用之后的语句,均按被调函数相反的顺序执行。
- 虽然每级递归都有自己的变量,但是并没有拷贝函数的代码。
- 递归函数必须包含能让递归调用停止的语句。

我个人认为递归就是把你要干的事情抽象一个成可以有限步数解决的函数,然后某一步解决不了就再调用这个函数,直到可以解决(结束递归的条件)这个问题就返回。
下面再看一个具体的例子来了解递归。
二、汉诺塔问题
1.简要概括一下汉诺塔的故事
汉诺塔由法国数学家爱德华·卢卡斯创造,他曾经编写了一个印度的古老传说:
在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
2.回到编程,汉诺塔问题主要就是解决这个问题:
有A、B、C三根针,A上从小到大放着n层盘子,要从A上所有的盘子移动到C盘上。
条件是一次只能移动一个盘子,无论什么时候小盘子必须在大盘子上面。
汉诺塔问题求的是把盘子从A移到C总共的移动次数是多少。
这是我之前追踪四层汉诺塔运行步骤画的笔记


事实证明,没多大帮助。
要想理解递归必须要放弃理解递归,放弃跟踪全程步骤。
解决问题是计算机的事,你只要明确要把每一步怎么传给计算机,递归两层之间怎么交接,以及递归结束的条件就可以。
3.怎么解决汉诺塔问题
要解决汉诺塔问题就要用到递归思想,这里拿四层汉诺塔举例子:
要完成四层汉诺塔,需要先把第四层盘子从A柱放到C柱,而要把第四层盘子放到C柱,就要把上面三层的盘子放到B柱:

那么要把这三层盘子移到B柱,那么就要先把第三层盘子移到B柱。
要把第三层盘子移到B柱,就要把第二层盘子移到C柱子。
要把第二层盘子移到C柱,就要把第一层盘子移到B柱子。
移动一层汉诺塔到另一个柱不简单吗?
这样子把问题解决了,第四层盘子就可以移动到C柱上了。
然后把剩下的三层汉诺塔也按照上面的思想,就可以移动到C柱上了。
4.具体代码实现
把大象装进冰箱需要多少步
- 把冰箱门打开
- 把大象放进去
- 把冰箱门关上
把汉诺塔放到C柱需要多少步
- 把底层上面的盘子放到B柱
- 把最底层盘子放到C柱
- 把B柱那些盘子放到C柱
抽象一下就是:
- 把n-1层盘子从起点移到暂存区
- 然后把第n层盘子从起点移到终点
- 然后把n-1层盘子从暂存区移到终点
在这里可以创建一个move函数来移动盘子
void move(int pile, char src, char tmp, char dst);
src就是源起点,tmp就是暂存区,dst就是终点
最外层的move函数完成的是把pile层汉诺塔从src经过tmp移动到dst
现在要把大象装进冰箱了
在move函数里面调用move函数来解决之后的问题:
1. 把冰箱门打开
move(pile - 1, src, dst, tmp);
这层move完成的是把pile-1层汉诺塔从src经过dst移动到tmp
2.把大象塞进去
move(1, src, tmp, dst);
这层move完成的是把最底层汉诺塔盘子从src直接移动到dst
3.把门关上
move(pile - 1, tmp, src, dst);
这层move完成的是把pile-1层汉诺塔从tmp经过src移动到dst
每一层move函数都有他自己的起点、暂存区和终点,我们只需要把上一层的起点、暂存区和终点传过去就行了。
5. 完整代码
以下是完整代码:
#include<stdio.h>
#include<stdlib.h>
#define MAX_LEVEL 30 //设置最大层数
int steps = 0;//steps保存盘子移动次数
void move(int pile, char src, char tmp, char dst);
int main(void)
{
int levels = 0;
printf("输入汉诺塔层数(1~%d):", MAX_LEVEL);
scanf("%d", &levels);
if (levels > 0 && levels < 30)//判断是否符合层数范围
{
move(levels, 'A', 'B', 'C');
printf("共移动了%d次。\n", steps);
system("pause");
return 0;
}
printf("输入范围错误\n");
system("pause");
return 1;
}
void move(int pile, char src, char tmp, char dst)
{
if (pile == 1)//pile=1问题就好解决了
{
printf("%c --> %c\n", src, dst);
steps++;
return;
}
move(pile - 1, src, dst, tmp);
move(1, src, tmp, dst);
move(pile - 1, tmp, src, dst);
}
运行结果如下:

C语言汉诺塔递归算法实现的更多相关文章
- C语言之算法初步(汉诺塔--递归算法)
个人觉得汉诺塔这个递归算法比电子老鼠的难了一些,不过一旦理解了也还是可以的,其实网上也有很多代码,可以直接参考.记得大一开始时就做过汉诺塔的习题,但是那时代码写得很长很长,也是不理解递归的结果.现在想 ...
- python的递归算法学习(3):汉诺塔递归算法
汉诺塔问题是递归函数的经典应用,它来自一个古老传说:在世界刚被创建的时候有一座钻石宝塔A,其上有64个金蝶.所有碟子按从大到小的次序从塔底堆放至塔顶.紧挨着这座塔有另外两个钻石宝塔B和C.从世界创始之 ...
- C语言 汉诺塔问题
//凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 汉诺塔是由三根杆子A,B,C组成的.A杆上有n个(n>1)穿孔圆盘,盘的尺寸由下到上依次变小.要求按 ...
- 题目1458:汉诺塔III(不一样的汉诺塔递归算法)
题目链接:http://ac.jobdu.com/problem.php?pid=1458 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...
- c语言-汉诺塔递归调用
#include<stdio.h> int main() { void hano_tower(int n,char one,char two,char three); int m=0; p ...
- C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)
本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...
- 汉诺塔(河内塔)算法 ----C语言递归实现
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子, 在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺 ...
- 【C语言】汉诺塔问题
之前遇见这个问题,非常费劲地理解了,并写出代码,然后过段时间,再遇见这个问题,又卡住了,如此反反复复两三次,才发现自己对递归的理解依然很肤浅.今天无聊,重温<算法:c语言实现>一书,又遇见 ...
- 运用Turtle实现汉诺塔的可视化运行(递归算法)
运用Turtle实现汉诺塔的可视化运行(递归算法) 汉诺塔问题又名河内塔问题,是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆 ...
- 汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法
非递归算法: 根据圆盘的数量确定柱子的排放顺序: 若n为偶数,按顺时针方向依次摆放 A B C: 若n为奇数,按顺时针方向依次摆放 A C B. 然后进行如下操作: (1)按顺时针方向把圆盘1从现在的 ...
随机推荐
- MASA MAUI iOS 文件下载与断点续传
@ 目录 背景 介绍 方案及代码 1.新建MAUI项目 2.建立NSUrlSession会话连接 3.使用NSUrlSessionDownloadTask 创建下载任务 4.DidWriteData ...
- AcWing - 闫氏DP分析法
核心思想:从集合角度来分析DP问题 在我们遇到的DP问题中,一般都是求在一个有限集内的最值,但是这些方案数量一般都是指数级别的,想要一个一个查找出来不太可能.所以DP方法是用来优化这种寻找最优方案的过 ...
- Python基础——二分法、面向过程编程思想、有名函数、lambda、max、_min的应用、sorted排序、map的应用、filter的应用、reduce的应用
文章目录 内容回顾 二分法 伪代码模板 面向过程编程思想 函数式 def用于定义有名函数 lambda用于定义匿名函数 调用匿名函数 匿名函数作用 匿名函数的示范 max的应用 min的应用 sort ...
- 高可用mongodb集群(分片+副本):规划及部署
目录 ■■ 概述 ■ 下图是一个典型的3节点分片副本集群 ■ Mongos Server ■ config server ■ shard server ■ replica set ■ 仲裁者(Arbi ...
- ORA-10456: cannot open standby database; media recovery session may be in progress
SQL> alter database recover managed standby database disconnect from session;Database altered.SQL ...
- HCTF 2023 wp
HCTF 2023 wp 一.Misc 1.玩原神玩的 分析:附件为一张图片 观察最后一行,明显有flag的格式 搜索得知是 对照得flag为:hctf{yuanlainiyewanyuanshenh ...
- Typora +Picgo 搭建个人笔记
目录 Typora +Picgo 搭建个人笔记 一.Picgo +Github 搭建图床 1.基础设置 2. 将配置导出,方便下次使用 二.Typora:设置 : 1. 基本设置 2. 导出自动提交 ...
- select...for update到底是加了行锁,还是表锁?
前言 前几天,知识星球中的一个小伙伴,问了我一个问题:在MySQL中,事务A中使用select...for update where id=1锁住了,某一条数据,事务还没提交,此时,事务B中去用sel ...
- FWT & FMT(位运算卷积)学习笔记
它们两个的全名叫 快速沃尔什变换(FWT) 和 快速莫比乌斯变换(FMT),用来在 \(O(n\log n)\) 时间复杂度内求位运算卷积. 因为 FMT 能解决的问题是 FWT 的子集,所以这里不讲 ...
- LNOI 2023 游记
Day -1 持续性的精神状态不太好,分明睡觉起床时间都没变,但白天就是非常非常困,为什么呢. 补不动任何题,脑子完全不转...... Day 0 13:30 才被家长叫醒,四点左右到了开发区还是好困 ...