当前位置: 首页 > news >正文

35.【C语言】详解函数递归

目录:

定义

作用

例子1~3

拓展学习

趣味练习

1.定义:函数自己调用自己(推回

int main()
{main()return 0;
}

这样容易死循环,导致爆栈(Stack Overflow)

所以需要设立限制条件,使执行时越来越接近条件,满足限制条件时停止递归

2.作用:大事画小,小事化了(大问题变多个子问题)

3.例子1

之前写过(迭代)E5.【C语言】练习:计算n的阶乘

但不是用递归实现的

递归思路:n!=n*(n-1)!

                  5!=5*4!=5*4*3!=5*4*3*2!=5*4*3*2*1(逐渐展开化解问题)

写成伪代码:n!=n*fact(n-1)=n*(n-1)*fact(n-2)=...=n*(n-1)*(n-3)*...*1(递推到限制条件后,再回归,即代入数据计算)

特例:0!==1

思路:写一个函数fact(factorial n.阶乘)

1ed77d862a4f4324a8fac785f5c621c1.png

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int fact(int n)
{if (0 == n)//限制条件return 1;elsereturn n * fact(n - 1);
}
int main()
{int n = 0;scanf("%d", &n);int a = fact(n);printf("%d\n", a);
}

ba2d941bbe674991aa335167a534828d.png

注意:每次调用时要向栈区申请内存空间来存放信息,该空间叫运行时堆栈或函数栈帧空间

计算完后销毁

4.例子2

之前写过E16.【C语言】练习:输入一个正的整数,逆序打印这个整数的每一位

不是用递归写的

现创建函数print

写成伪代码:print(1234)==printf("%d",4);+print(123);=printf("%d",4);+printf("%d",3");+print(12);=...

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int print(int n)
{if (n != 0){printf("%d", n % 10);print(n / 10);}
}
int main()
{int n = 0;scanf("%d", &n);print(n);
}

如果改成:输入一个整数,正序打印(即回归时打印)该整数的每一位

输入:1234

输出:1 2 3 4

略作改动

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int print(int n)
{if (n > 9){print(n / 10);}printf("%d ", n % 10);
}int main()
{int n = 0;scanf("%d", &n);print(n);
}

注意:当n>9时,并不会执行下面的printf(递推),一旦达到限制条件时,会printf每一位(回归)

5.例子3

求第n个斐波那契数(介绍)

这里写一个函数fbi,令fbi(0)=0; fbi(1)=1; fbi(2)=1;

核心公式是fbi(n)==fbi(n-1)+fbi(n-2)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int fbi(int n)
{if (1 == n || 2 == n){return 1;}else{return fbi(n - 1) + fbi(n - 2);}
}int main()
{int n = 0;scanf("%d", &n);int a=fbi(n);printf("%d\n", a);
}

但输入较大的数字计算很慢

可以用循环实现

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int fbi(int n)
{int sum = 0;int a = 1;int b = 1;int c = 0;if (1 == n || 2 == n){return 1;}else{while (sum < n - 2){c = a + b;a = b;b = c;sum++;}return c;}
}int main()
{int n = 0;scanf("%d", &n);int a=fbi(n);printf("%d\n", a);
}

改动后还可以打印前n个斐波那契数

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int fbi(int n)
{int sum = 0;int a = 1;int b = 1;int c = 0;if (1 == n){printf("1");}else if (2 == n){printf("1 1");}else{printf("1 1");while (sum < n - 2){c = a + b;a = b;b = c;sum++;printf(" %d",c);}return c;}
}int main()
{int n = 0;scanf("%d", &n);fbi(n);
}

6.拓展学习

*青蛙跳台阶

一共n个台阶,青蛙一次可以跳1个或2个台阶,一共有多少种跳法?

思路:可以倒推,从终点起,可以从第n-1阶跳下或第n-2阶调下

所以jump(n)=jump(n-1)+jump(n-2)

*汉诺塔

A柱有n个盘子,上小下大,现要将A柱的盘子全部移动到C盘(可以借助B柱),但要保证ABC三柱始终保持盘子上小下大且在三根柱子之间一次只能移动一个圆盘,求一共需要多少步
简单思路:仍然倒推,最终一定是n-1个盘在B柱,A柱只剩下最大的盘-->n-1=(n-2)+1 n-2个盘在B柱,A柱剩次大的盘,C柱有最大的盘-->......

7.趣味练习

 2022全国乙卷,有兴趣的可以写代码试试

点击查看答案(第E21篇) 

http://www.lryc.cn/news/407942.html

相关文章:

  • 【机器学习】智驭未来:机器学习如何重塑制造业的转型与升级
  • Python爬虫(5) --爬取网页视频
  • 【Unity】关于Luban的简单使用
  • 企业公户验证API如何使用JAVA、Python、PHP语言进行应用
  • 杰发科技Bootloader(2)—— 基于7840的Keil配置地址
  • cmd常用命令
  • PCIe 以太网芯片 RTL8125B 的 spec 和 Linux driver 分析备忘
  • Python tkinter Menu菜单组件详解
  • 谷粒商城实战笔记-46-商品服务-API-三级分类-配置网关路由与路径重写
  • 简要了解sql注入
  • Java 扫雷游戏
  • vue3 命令运行窗口暴露网络地址,以及修改端口号
  • 由CANoe自带协议栈在TCP断开连接时同时发送两条FIN报文引起的注意事项
  • FastGPT部署和接入使用重排模型bce-reranker-base
  • Android笔试面试题AI答之线程Handler、Thread(2)
  • 某某物联rabbitmqhttp二轮充电桩协议充电协议对接
  • 黑马JavaWeb企业级开发(知识清单)03——HTML实现正文:排版(音视频、换行、段落)、布局标签(div、span)、盒子模型
  • Java | Leetcode Java题解之第283题移动零
  • Django REST Framework(十三)视图集-GenericViewSet
  • 《0基础》学习Python——第二十四讲__爬虫/<7>深度爬取
  • Python Pygame制作简单五子棋游戏
  • JS+H5在线文心AI聊天(第三方接口)
  • kafka源码阅读-ReplicaStateMachine(副本状态机)解析
  • 【MetaGPT系列】【MetaGPT完全实践宝典——如何定义单一行为多行为Agent】
  • Kolla-Ansible的确是不支持CentOS-Stream系列产品了
  • IDEA启动C:\Users\badboy\.jdks\corretto-17.0.7\bin\java.exe -Xmx700m报错
  • ctfshow298-300(java信息泄露,代码审计)
  • Java 基础 and 进阶面试知识点(超详细)
  • 【LabVIEW作业篇 - 5】:水仙花数、数组与for循环的连接
  • Kafka系列之如何提高消费者消费速度