当前位置:网站首页>通过斐波那契数再谈函数递归2.0
通过斐波那契数再谈函数递归2.0
2022-07-31 12:10:00 【林深方见鹿】
上次我们通过几个简单的例子,认知到递归可以大大的减少代码量,方便使用,这次我们再结合斐波那契数来深入认识一下函数递归。
代码1.0,通过递归实现
#define _CRT_SECURE_NO_WARNINGS
//求第n个斐波那契数(不考虑溢出)
#include<stdio.h>
int fib(int n)
{
if (n <= 2)
return 1;
else
return (fib(n - 1) + fib(n - 2));
}
int main()
{
int n = 10;
int res = fib(n);
printf("%d ", res);
return 0;
}
运行结果:
当我们把n取较大数的时候,能够明显发现程序耗时是很长的,说明递归的效率可能不高,当求第50个斐波那契数时,特别耗费时间,当n过大时,程序可能就会崩溃了,这是为什么呢?是因为在递归调用的过程中,很多数据会被重复计算,我们通过下面的代码来看一下:
这是求n=10的斐波那契数,我们用全局变量count来对此过程中求n=3的斐波那契数进行计数,直观的来看看到底重复计算的次数有多少。
#define _CRT_SECURE_NO_WARNINGS
//求第n个斐波那契数(不考虑溢出)
#include<stdio.h>
int count = 0;
int fib(int n)
{
if (n == 3)
count++;
if (n <= 2)
return 1;
else
return (fib(n - 1) + fib(n - 2));
}
int main()
{
int n = 10;
int res = fib(n);
printf("%d \n", res);
printf("%d \n", count);
return 0;
}
运行结果:
我们可以看出,在计算fib(10)的过程中,计算fib(3)的次数为21,这么多的重复计算就造成了程序十分的低效率,所以我们在使用递归的过程中一定要考虑到程序的效率问题,而且当n过大时,也会引起程序的崩溃。
参数过大会引起栈溢出,因为系统分配给程序的栈空间是有限的,但是在递归过程中,不断的开辟新空间,最终产生了栈空间耗尽的情况,造成了栈溢出,程序就会崩溃。
那么由递归引起的低效率问题和栈溢出该如何解决呢?
将递归改为非递归;使用static对象代替nonstatic局部对象。
我们来看看改进后的求斐波那契数的程序,用非递归实现。
#define _CRT_SECURE_NO_WARNINGS
//求第n个斐波那契数(不使用递归)
#include<stdio.h>
int fib(int n)
{
int result = 1;
int firstnum;
int secondnum;
firstnum = secondnum = 1;
while (n > 2)
{
n -= 1;
firstnum = secondnum;
secondnum = result;
result = firstnum + secondnum;
}
return result;
}
int main()
{
int res = fib(10);
printf("%d \n", res);
return 0;
}
运行结果:
我们通过循环来实现函数,可能会导致代码数量的增加,但是同时也提高了效率。
递归会使复杂的问题变简单,所以许多问题我们是用递归来进行解释的,因为递归比非递归的形式更加清晰,代码的思想一目了然,不过通过其他方法例如循环实现效率往往更高,但是代码的可读性可能会变差,那我们遇到问题时,到底用递归吗?这个时候如果问题过于复杂,难以用循环(迭代)来实现的话,此时递归可以以它的简洁性来补偿它所带来的运行时的开销。
边栏推荐
- Exploring Plain Vision Transformer Backbones for Object Detection 论文阅读笔记
- Selenium自动化测试之Selenium IDE
- JVS低代码能力简介及功能清单
- Json和对象之间转换的封装(Gson)
- imx6ull看门狗使用
- 想吃菌子,当然是自己上山找了
- Docker build Mysql master-slave replication
- Three-tier architecture service, dao, controller layer
- Life is endless, there are more questions, simple questions to learn knowledge points
- Redis学习笔记-3.慢查询和其他高级数据结构
猜你喜欢
The item 'node.exe' was not recognized as the name of a cmdlet, function, script file, or runnable program.
Initial JDBC programming
ESP8266-Arduino编程实例-MCP9808数字温度传感器驱动
JVS函数公式使用场景介绍
Acwing第 62 场周赛【未完结】
Shengxin Weekly Issue 38
LeetCode - 025. 链表中的两数相加
Docker安装canal、mysql进行简单测试与实现redis和mysql缓存一致性
一文吃透接口调用神器RestTemplate
MySQL row-level locks (row locks, adjacent key locks, gap locks)
随机推荐
SAP ABAP OData 服务如何支持 $filter (过滤)操作试读版
deeplab implements its own remote sensing geological segmentation dataset
The latest MySql installation teaching, very detailed
Power BI----几个常用的分析方法和相适应的视觉对象
Spark GC日志分析
双非一本进字节了!!纯干货分享
Chrome开发自定义右键菜单实现快速跳转到指定页面
基于稳态视觉诱发电位和注意力脑电的混合脑机接口系统
基于生物激励神经网络的室内实时激光SLAM控制方法
Use docker to build mysql master-slave
MySQL日志中“binlog”的三种格式玩起来真爽
Summary of several defragmentation schemes for MySQL (to solve the problem of not releasing space after deleting a large amount of data)
「R」使用ggpolar绘制生存关联网络图
Obsidian设置图床
Exploring Plain Vision Transformer Backbones for Object Detection Paper Reading Notes
CameraToolUnity中两种摄像机的两种观察控制方式
榕树贷款GPU 硬件架构
立方体IV(暑假每日一题 10)
Qt鼠标穿透
数据湖(十九):SQL API 读取Kafka数据实时写入Iceberg表