递归以及斐波那契数列递归算法和迭代算法的实现与分析

这篇具有很好参考价值的文章主要介绍了递归以及斐波那契数列递归算法和迭代算法的实现与分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

递归

程序调用自身的编程技巧称为递归( recursion)
递归有两个过程,简单地说一个是递的过程,一个是归的过程
递归的两个必要条件
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2.每次递归调用之后越来越接近这个限制条件
.
递归本质就是函数调用,是函数调用,本质就要形成和释放栈帧,调用函数是有成本的,这个成本就体现在形成和释放栈帧上:时间+空间.递归就是不断形成栈帧的过程
通过上述我们也能了解到递归的一些限制

  1. 内存和CPU的资源是有限的,也就决定了,合理的递归是绝对不能无限递归下去
  2. 递归不是什么时候都能用,而是要满足自身的应用场景,即:目标问题的子问题,也可以采用相同的算法解决,本质就是分治的思想
  3. 核心思想:大事化小+递归出口

斐波那契数列

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……

在讲解递归斐波那契数列之前,我们需要明白递归的本质

通过如上定义,我们可以定义讲用代码去实现斐波那契数列
首先来看递归版本的代码

递归版

int Fib(int n)
{	
	if(n<=0)
	{
		return 0;
	}
	else if (1 == n || 2 == n)
	{
		return 1;
	} 
	return Fib(n - 1) + Fib(n - 2);
} 
int main()
{
	int n = 5;
	int x = Fib(n);
	printf("fib(%d): %d\n", n, x);
	return 0;
}

递归以及斐波那契数列递归算法和迭代算法的实现与分析,算法,开发语言,c语言,学习这就是上式当n=5,即Fib(5)所形成的递归调用理论图

而上述提到递归的本质是函数调用,由此可见,当n的值越大时(即所求的斐波那契数越大),调用的函数就越来越多,所以我们在此的时间成本和空间成本都非常之高
(时间复杂度为O(2^N),空间复杂度为O(N)).

通过如下代码可以证明

int main()
{
	int n = 10; //n从40开始,时间就会慢慢增大得明显
	//使用win提供的GetTickCount()函数,来获取开机到现在的累计时间(单位毫秒)
	double start = GetTickCount(); 
	int x = Fib(n);
	double end = GetTickCount();
	printf("%lf ms\n", (end - start));//二者进行相减就可以算出递归所用时间
	system("pause");
	return 0;
}

n从40开始时,时间就会明显变大,此时n即使每次只加1来测试时间,时间就会变大很多,这是因为从上面得递归调用理论图也可以看出,当F(4)变为F(5)的时候,F(4)分支下的F(3)及后面一系列都将出现在F(5)的另一边分支上,由此可见当F(40)变为F(41)时,F(39)及其一系列将会出现在F(41)的另一端分支上,所以即使每次只加1,变化也是巨大的

接下来我们采用迭代的思想来进行时间和空间上效率的提升(说直白点迭代就是循环)

迭代版

int Fib(int n)
{
	int *dp = (int*)malloc(sizeof(int)*(n+1)); //多加一个是为了下标保持一致方便计算
	//[0]不用(当然,也可以用,不过这里我们从1开始,为了后续方便)
	dp[1] = 1;
	dp[2] = 1;
	int i = 3;
	while(i<=n)
	{
		dp[i] = dp[i - 1] + dp[i - 2];
		i++;
	} 
	int ret = dp[n];
	free(dp);
	return ret;
}

其实这也算一种动态规划的算法,但是我们也能看出一些弊端,即我们将从第1位到第n位斐波那契数列都保存在了我们malloc出来的堆空间里面(空间复杂度时O(n)),然而任何一个斐波那契数都只与前面两个数有关,所以我们可以进行更近一步的优化

加强迭代版

int Fib(int n)
{
	int first = 1;
	int second = 1;
	int third = 1;
	while (n > 2){
		third = second + first;
		first = second;
		second = third;
		n--;
	} 
return third;
}

这个迭代版本的代码完美在时间和空间复杂度上都进行了极大的优化

总结

综上,我们也可以通过斐波那契的例子看出递归算法的在效率上一般不是很高,而迭代在效率上要高于递归.但是递归相对而言代码要比迭代简单一点,代码的可读性较强
递归运用较多的场景在于:
1.当问题和子问题具有递推关系(阶乘)。
1.具有递归性质的数据结构(链表、树)。

因此递归函数也只是一种解决问题的技巧,它和其它技巧一样,也存在某些缺陷,具体来说就是:递归函数的时间开销和内存开销都非常大,甚至在极端情况下会导致程序崩溃(所以递归函数一定递了之后要归,不然最终会造成栈溢出)。所以我们在今后使用递归时,也要时刻考虑这一点文章来源地址https://www.toymoban.com/news/detail-652716.html

到了这里,关于递归以及斐波那契数列递归算法和迭代算法的实现与分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 编写递归函数,求斐波那契数列第n项

    要求: 编写递归函数int f(int n),计算如下公式: 定义main函数输入n,调用f函数进行计算,在main函数中输出计算结果。 【样例输入】 10 【样例输出】 89 主函数: #includestdio.h int main() {     int i,n;     printf(\\\"请输入你要打印的斐波那契数列项数:n\\\");     scanf(\\\"%d\\\",n);//n为打印的

    2024年02月04日
    浏览(48)
  • 递归详解,斐波那契数列、二叉树遍历、汉诺塔问题的递归代码

    一、递归详解 [1] 递归是一种编程技巧,通过函数调用自身来解决问题。递归中包含三个要素:递归定义、递归出口和递归调用。 [2] 递归定义指的是问题可以被分解为同类且更小规模的子问题。在递归过程中,问题会不断被分解为规模更小的子问题,直到达到一个基本情况,

    2024年02月08日
    浏览(33)
  • 【第37天】斐波那契数列与爬楼梯 | 迭代的鼻祖,递推与记忆化

    本文已收录于专栏 🌸《Java入门一百例》🌸

    2024年01月20日
    浏览(31)
  • 斐波那契数列、青蛙跳台阶、汉诺塔(C语言Java通用)、递归练习题

    Write once,Runanywhere. 🔥🔥🔥 本派文章详细斐波那契数列、青蛙跳台阶、汉诺塔(C语言Java通用)、递归练习题。 💥 💥 💥 如果你觉得我的文章有帮助到你,还请【关注➕点赞➕收藏】,得到你们支持就是我最大的动力!!! 💥 💥 💥 ⚡ 版权声明:本文由【马上回来了】原创、

    2023年04月08日
    浏览(33)
  • 【算法】斐波那契数列通项公式

    如果数列 a n a_n a n ​ 的递推公式: a n = c 1 a n − 1 + c 2 a n − 2 a_n=c_1a_{n-1}+c_2a_{n-2} a n ​ = c 1 ​ a n − 1 ​ + c 2 ​ a n − 2 ​ ------(1) 根据待定系数法,假设 a n − x a n − 1 = y ( a n − 1 − x a n − 2 ) a_n-xa_{n-1}=y(a_{n-1}-xa_{n-2}) a n ​ − x a n − 1 ​ = y ( a n − 1 ​ − x a n − 2 ​

    2023年04月24日
    浏览(39)
  • 【算法学习】斐波那契数列模型-动态规划

            我在算法学习过程中,针对斐波那契数列模型的动态规划的例题进行了一个整理,并且根据标准且可靠一点的动态规划解题思路进行求解类似的动归问题,来达到学习和今后复习的必要。         所谓的斐波那契数列模型,即当前状态的值等于前两种状态的值之和。

    2024年02月04日
    浏览(47)
  • 【算法】斐波那契数列与台风的故事

    在小岛的一个海滨小镇上,住着一个名叫苏菲的女孩。苏菲一家人靠海为生,她的生活简单而朴素,与大自然和谐共生。每天,苏菲都会来到海边,欣赏那美丽的日出和日落,感受着大海的呼吸。 然而,小岛的美丽风光并非一成不变。每年夏季,热带气旋活跃,台风频繁登陆

    2024年02月10日
    浏览(36)
  • 动态规划入门:斐波那契数列模型以及多状态(C++)

        动态规划(Dynamic programming,简称 DP)是一种解决多阶段决策问题的算法思想。它将问题分解为多个阶段,并通过保存中间结果来避免重复计算,从而提高效率。 动态规划的解题步骤一般分为以下几步: 思考状态表示,创建dp表(重点) 分析出状态转移方程(重点) 初始化 确定

    2024年02月11日
    浏览(38)
  • C语言经典算法实例6:斐波那契数列

    斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89… 这个数列从第3项开始,每一项都等于前两项之和。 斐波那契数列的定义者,是意大利数学家莱昂纳多·斐波那契(Leonardo Fibonacci),生于公元1170年,卒于1250年,籍贯是比萨。 他被人称作“比萨的莱昂

    2024年02月02日
    浏览(40)
  • C++算法 —— 动态规划(1)斐波那契数列模型

    每一种算法都最好看完第一篇再去找要看的博客,因为这样会帮你梳理好思路,看接下来的博客也就更轻松了。当然,我也会尽量在写每一篇时都可以让不懂这个算法的人也能边看边理解。 动规的思路有五个步骤,且最好画图来理解细节,不要怕麻烦。当你开始画图,仔细阅

    2024年02月10日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包