一、什么是递归函数

函数调用自己的行为就是递归,递归必须要有终止条件,不然它会无限递归。

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. 每级调用都有自己的变量
  2. 每次函数调用都会返回一次
  3. 递归函数中位于递归调用之前的语句,均按被调函数的顺序执行。
  4. 递归函数中位于递归调用之后的语句,均按被调函数相反的顺序执行。
  5. 虽然每级递归都有自己的变量,但是并没有拷贝函数的代码。
  6. 递归函数必须包含能让递归调用停止的语句。

    我个人认为递归就是把你要干的事情抽象一个成可以有限步数解决的函数,然后某一步解决不了就再调用这个函数,直到可以解决(结束递归的条件)这个问题就返回。
    下面再看一个具体的例子来了解递归。

二、汉诺塔问题

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.具体代码实现

把大象装进冰箱需要多少步

  1. 把冰箱门打开
  2. 把大象放进去
  3. 把冰箱门关上

把汉诺塔放到C柱需要多少步

  1. 把底层上面的盘子放到B柱
  2. 把最底层盘子放到C柱
  3. 把B柱那些盘子放到C柱

抽象一下就是:

  1. 把n-1层盘子从起点移到暂存区
  2. 然后把第n层盘子从起点移到终点
  3. 然后把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语言汉诺塔递归算法实现的更多相关文章

  1. C语言之算法初步(汉诺塔--递归算法)

    个人觉得汉诺塔这个递归算法比电子老鼠的难了一些,不过一旦理解了也还是可以的,其实网上也有很多代码,可以直接参考.记得大一开始时就做过汉诺塔的习题,但是那时代码写得很长很长,也是不理解递归的结果.现在想 ...

  2. python的递归算法学习(3):汉诺塔递归算法

    汉诺塔问题是递归函数的经典应用,它来自一个古老传说:在世界刚被创建的时候有一座钻石宝塔A,其上有64个金蝶.所有碟子按从大到小的次序从塔底堆放至塔顶.紧挨着这座塔有另外两个钻石宝塔B和C.从世界创始之 ...

  3. C语言 汉诺塔问题

    //凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 汉诺塔是由三根杆子A,B,C组成的.A杆上有n个(n>1)穿孔圆盘,盘的尺寸由下到上依次变小.要求按 ...

  4. 题目1458:汉诺塔III(不一样的汉诺塔递归算法)

    题目链接:http://ac.jobdu.com/problem.php?pid=1458 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...

  5. c语言-汉诺塔递归调用

    #include<stdio.h> int main() { void hano_tower(int n,char one,char two,char three); int m=0; p ...

  6. C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)

    本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...

  7. 汉诺塔(河内塔)算法 ----C语言递归实现

    汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子, 在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺 ...

  8. 【C语言】汉诺塔问题

    之前遇见这个问题,非常费劲地理解了,并写出代码,然后过段时间,再遇见这个问题,又卡住了,如此反反复复两三次,才发现自己对递归的理解依然很肤浅.今天无聊,重温<算法:c语言实现>一书,又遇见 ...

  9. 运用Turtle实现汉诺塔的可视化运行(递归算法)

    运用Turtle实现汉诺塔的可视化运行(递归算法) 汉诺塔问题又名河内塔问题,是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆 ...

  10. 汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法

    非递归算法: 根据圆盘的数量确定柱子的排放顺序: 若n为偶数,按顺时针方向依次摆放 A B C: 若n为奇数,按顺时针方向依次摆放 A C B. 然后进行如下操作: (1)按顺时针方向把圆盘1从现在的 ...

随机推荐

  1. Redis持久化 (RDB和AOF) 梳理

    Redis有两种持久化方案: RDB持久化 AOF持久化 RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照.简单来说就 ...

  2. CAS中ABA问题的解决

    转自(here)   CAS问题的产生 在运用CAS做Lock-Free操作中有一个经典的ABA问题: 线程1准备用CAS将变量的值由A替换为B,在此之前,线程2将变量的值由A替换为C,又由C替换为A ...

  3. Linux下安装MySQL问题及报错解决

    前言: 在Linux环境下,安装MySQL服务 环境: 虚拟机CentOS7 \-----------------------------------------------\ 流程: 确保mysql ...

  4. Jmeter连接数据库sql语句操作,查询后取值做变量

    第一步 :导入jar包 第二步 :创建JDBC Reques 第三步 :创建JDBC Connection Configuration  第四步:在request中输入数据进行操作 Query Typ ...

  5. py2neo函数merge参数报错

    代码 a1 = Node("house", name='303') g.merge(a1) 执行报错 Primary label and primary key are requi ...

  6. 🎊OpenTiny Vue 3.11.0 发布:增加富文本、ColorPicker等4个新组件,迎来了贡献者大爆发!

    你好,我是 Kagol. 非常高兴跟大家宣布,2023年10月24日,OpenTiny Vue 发布了 v3.11.0 . OpenTiny 每次大版本发布,都会给大家带来一些实用的新特性,8.14 ...

  7. MySQL查看数据库性能常用命令和实战教学

    MySQL查看数据库性能常用命令 # 列出MySQL服务器运行各种状态值 show global status; # 查询MySQL服务器配置信息语句 show variables; # 慢查询 sh ...

  8. Redis宕机恢复

    AOF(Append Only File) Redis持久化:AOF日志 用 AOF 方法进行故障恢复的时候,需要逐一把操作日志都执行一遍.如果操作日志非常多,Redis 就会恢复得很缓慢,影响到正常 ...

  9. ChatGLM3-6B:新一代开源双语对话语言模型,流畅对话与低部署门槛再升级

    ChatGLM3-6B:新一代开源双语对话语言模型,流畅对话与低部署门槛再升级 1.ChatGLM3简介 ChatGLM3 是智谱AI和清华大学 KEG 实验室联合发布的新一代对话预训练模型.Chat ...

  10. Educational Codeforces Round 105 (Rated for Div. 2) A-C题解

    写在前边 链接:Educational Codeforces Round 105 (Rated for Div. 2) A. ABC String 链接:A题链接 题目大意: 给定一个有\(A.B.C ...