目录

一.什么是递归?

二. 汉诺塔问题

2.1 认识什么是汉诺塔

2.2 汉诺塔打印步数

2.3 汉诺塔打印步骤

三.青蛙跳台阶问题


一.什么是递归?

这里我们先简单的认识一下什么是函数递归:我们可以理解为在一个过程或函数在其定义或说明中直接或间接调用自身的的一个技巧我们称为函数递归。

递归的主要策略:就是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归的主要的思考方式:就是把大事化小

递归可以看成是两个部分:一个是递推,一个是回归

递归的两个必要条件:

1.存在限制条件,当满足这个限制条件的时候,递归便不再继续

2.每次递归调用之后越来越接近这个限制条

在简单的认识了递归后,就让我们一起来学习一下函数递归的一些经典问题。

二. 汉诺塔问题

2.1 认识什么是汉诺塔

汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

2.2 汉诺塔打印步数

目的:用递归的方式计算一个n层的汉诺塔从A柱到C柱所需要的步数。

规律:经过例表我们可以发现n层塔所需要的步数就是2的n次方-1。

如何用递归来表示呢?

我们可以表示为:2*f(n-1)+1 的一个递推式(up因懒惰未做解释,见谅^-^)

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>int Hanio_steps(int num)
{if (num == 1)return 1;elsereturn 2 * Hanio_steps(num - 1) + 1;
}int main()
{int n = 0;scanf("%d", &n);int ret = Hanio_steps(n);printf("%d\n", ret);return 0;
}

2.3 汉诺塔打印步骤

前面我们已经知道了n层汉诺塔的步数,那n层汉诺塔 是如何从A柱移动到C柱呢?让我们一起来寻找一下规律。在移动的过程中,保证小圆盘再大圆盘的上面。

当只有一个圆盘的时候,直接将圆盘从A柱移动到C柱  A->C

当有两个圆盘的时候,我们需要先把一个圆盘移到B柱,然后把2盘子移到到C柱,再把B柱上的1盘子移动到C柱。  A->B,A->C,B->C

现在假设我们有n个圆盘,既n>=2,这个时候我们把n-1看成一个整体,这样就是第n-1个圆盘和第n个圆盘。规律如下:

1.首先,我们把n-1这一堆圆盘借助C柱放到B柱上.  A->C,C->B

2.再把最大的圆盘放到C柱中。 A->C

3.最后我们再把n-1这一堆圆盘借助A柱放到C柱上 。 B->A,A->C

思路整理:

当n==1时,直接将盘子从A移动到C

当n>1时,我们可以拆分成三个步骤:

1.先将n-1个盘子从A移到B中

2.再将编号为n的盘子从A移动到C中

3.最后将n-1个盘子从B移到C中

再这个过程中我们会发现1.3就是在进行一个递归

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>Hanio_process(int n, char a,char b,char c)
{if (n == 1){printf("%c->%c\n", a, c);}else{//  n-1的圆盘从A柱移到B柱Hanio_process(n - 1, a,c,b);//  将n层圆盘从A柱移动到C柱printf("%c->%c\n", a, c);//  再将n-1的圆盘从B柱移动到C柱Hanio_process(n - 1, b, a, c);}
}int main()
{int n = 0;printf("请输入层数:");scanf("%d", &n);Hanio_process(n,'A','B','C');return 0;
}

三.青蛙跳台阶问题

问题详细:一只青蛙一次最少跳一个台阶,一次最多跳两个台阶,求:青蛙跳上第n层台阶的时候有多少种跳法。

问题分析:

一层台阶:1种跳法

二层台阶:2种跳法

三层台阶:3种跳法

四层台阶:5种跳法

……

如果我们这里列一个数列:

1 2 3 5 8 13 21 34  55…

这个时候我们就会发现该数列由1和2开始,后面的每一项的数都是前面两项数字的和。

这时候是不是会发现有那熟悉的味道了,没错这个青蛙跳台阶的问题就是一个隐藏的

斐波那契数列问题。

规律:

F(1)=1,F(2)=2

当n>=3时,F(n)=F(n-1)+F(n-2)

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>int Jump_method(int n)
{if (n ==1){return 1;}else if (n == 2){return 2;}else{return Jump_method(n - 1) + Jump_method(n - 2);}
}int main()
{int n = 0;printf("输入台阶层数:");scanf("%d", &n);int ret=Jump_method(n);printf("共有%d种跳法\n",ret);return 0;
}

后文:

看了一下午才理解汉诺塔这个问题,也参考了很多优秀大佬的解释,在此非常感谢各位大佬的优秀好文。

C语言函数递归—经典递归问题相关推荐

  1. 汉诺塔——经典递归问题(c语言实现)

    汉诺塔--经典递归问题(c语言实现) 问题背景 汉诺塔问题是一个经典的问题.汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下 ...

  2. C语言中递归什么时候能够省略return引发的思考:通过内联汇编解读C语言函数return的本质...

    C语言中递归什么时候能够省略return引发的思考:通过内联汇编解读C语言函数return的本质 事情的经过是这种,博主在用C写一个简单的业务时使用递归,因为粗心而忘了写return.结果发现返回的结 ...

  3. c语言用参数确认递归,C语言程序设计(第4章函数)3

    4.3 函数的调用与参数 如果一个函数要使用参数,它就必须定义接受参数值的变量. 4.3.1 形式参数与实际参数 函数定义时填入的参数我们称之为形式参数,简称形参,它们同函数内部的局部变量作用相同.形 ...

  4. C语言函数递归调用实验报告,C语言函数的递归和调用实例分析

    一.基本内容: C语言中的函数可以递归调用,即:可以直接(简单递归)或间接(间接递归)地自己调自己. 要点: 1.C语言函数可以递归调用. 2.可以通过直接或间接两种方式调用.目前只讨论直接递归调用. ...

  5. c语言中fact函数怎么调用,C语言程序题: 1、编写一个求n!的函数fact(n),要求fact函数分别用递归和非递归两种方法实现...

    点击查看C语言程序题: 1.编写一个求n!的函数fact(n),要求fact函数分别用递归和非递归两种方法实现具体信息 答:int fac(int n) //非递归{int f=1; for(;n;) ...

  6. C语言函数(函数嵌套、递归调用)+局部变量和全局变量+extern关键字的使用+Visual Studio简单的使用教程+数据存储类别+内部函数外部函数

    上一篇文章:编译预处理知识点梳理:宏定义+文件包含+条件编译 C语言函数(函数嵌套.递归调用--+局部变量和全局变量+extern关键字的使用+Visual Studio简单的使用教程+数据存储类别+ ...

  7. C++两个函数可以相互递归吗_[算法系列] 搞懂递归, 看这篇就够了 !! 递归设计思路 + 经典例题层层递进

    [算法系列] 搞懂递归, 看这篇就够了 !! 递归设计思路 + 经典例题层层递进 从学习写代码伊始, 总有个坎不好迈过去, 那就是遇上一些有关递归的东西时, 看着简短的代码, 怎么稀里糊涂就出来了. ...

  8. c语言模板函数调用自定义函数调用,C语言函数的递归和调用

    C语言函数的递归和调用Tag内容描述: 1.计算机科学系陈垚,1,张福祥主编辽宁大学出版社,C语言程序设计,计算机科学系陈垚,2,我们先看这样一个例子:,说有一只调皮的小猴子,摘了一堆水果,第一天吃了 ...

  9. 什么叫c语言函数递归,什么是递归-C语言函数递归-嗨客网

    C语言函数递归教程 函数递归就是一个 C语言函数递归条件 执行一个函数时,就创建一个新的受保护的独立空间(新函数栈). 函数的局部 递归必须向退出递归的条件逼近,否则就是无限递归了. 当一个函数执行完 ...

最新文章

  1. 使用system语句出现不明确问题
  2. java统计大于0的个数_java中0的问题(依据0统计数量时出错)
  3. 自己写的小程序 deb打包
  4. GD32通用定时器、高级定时器PWM输出例程
  5. android 使用xml布局自己的对话框
  6. Linux作者批评英特尔指令集,英特尔回应 Linus Torvalds 对 AVX512 的批评
  7. 自动化特征提取器:图像特征提取和深度学习
  8. 20190805:两个队列实现栈
  9. android 监听连接超时,android – Retrofit和OkHttpClient,在失败方法中捕获连接超时
  10. js 数组合并并且去重
  11. OKR教练:OKR评分,你可以这样做。
  12. 路飞学城Python-Day8
  13. 搭建HTTP Live Streaming直播系统
  14. 鼠标连接在计算机,鼠标怎么连接在电脑上
  15. 人工客服为什么总是接不通?
  16. 关于网络传输中速度达不到很高的原因
  17. 1005【顺序结构】马克与爸爸的年龄问题
  18. 打印计算机准考证显示用户名未设置,职称计算机准考证打印时间须知2019年9月...
  19. shell while true
  20. 天美服务器维护,王者荣耀亚瑟皮肤特效丢失什么时候会修复?新皮肤特效消失天美紧急修复...

热门文章

  1. 华为v3鸿蒙系统_安卓系统:鸿蒙系统,正式再见
  2. 有多久没有这么疯狂了?
  3. C++产生随机数函数rand()
  4. 第十三天 06-文本编辑器VI的使用修改网卡等
  5. 虚拟地址和物理地址及其映射
  6. 一文轻松明白 Base64 编码原理
  7. 小程序开发 和html的区别,h5和小程序有什么区别?
  8. Linux中磁盘分区清理方法
  9. 设置EditText输入的文字全部变成大写或小写
  10. 2023北京物资学院计算机考研信息汇总