☆ Welcome to House's blog ! ☆
本人主页:神王豪斯(重拾基础期)-CSDN博客
本文讲的是函数递归经典问题之一——斐波那契数及其延伸青蛙跳台问题,若对函数递归概念有些模糊的话可以看一下我往期的博客 C语言修炼秘籍之——函数递归-CSDN博客 (链接放在这里啦,点击直接穿越~),若文章中有哪些地方说的不对、不够清晰,或者代码有哪里可以改进一下的就有劳大家打在评论区啦~那我们废话不多说,直接开始吧!
1.斐波那契数
1.1 问题引入
什么是斐波那契数?咱度娘是这么说的:
斐波那契数列(Fibonacci sequence),又称黄金分割数列 [1],因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34……
在数学上,这一数列以如下递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。
(优美的斐波那契曲线~)
1.2 问题解析
通过上述内容我们了解到,F(1) = F(2) = 1;从F(3)开始,F(n)=F(n-1)+F(n-2);
因此,我们便可确定解决此问题的大致框架:
1.3代码实现
根据已经搭出的框架,我们便可写出Fibonacci斐波那契数函数:
int Fibonacci(int n)
{
if (n == 1 || n == 2)
{
return 1;
}
else {
return (Fibonacci(n - 1) + Fibonacci(n - 2));
}
}
所有代码~
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int Fibonacci(int n)
{
if (n == 1 || n == 2)
{
return 1;
}
else {
return (Fibonacci(n - 1) + Fibonacci(n - 2));
}
}
int main()
{
int x = 0;
printf("要算第几个数字?\n");
scanf("%d", &x);
printf("%d",Fibonacci(x));
return 0;
}
运行结果~
通过上述的方法便可精确地计算出我们想要的斐波那契数列中的数字啦~
1.4 运行过程
“什么?真的能算所有我们想要的斐波那契数列中的数吗?我直接试一手50 ~Ψ( ̄∀ ̄)Ψ”
......
“我等老半天就出来个这?而且怎么也不能是负数吧 o(╥﹏╥)o”
还记得我们之前说过的吗,函数递归会将大的任务一步步往下拆分成小的任务,知道晓得被完成后再一步步昂往回传递结果,回传之前,上面的所有任务都是时刻待命的,当任务量太多且没有及时解决,就会出现栈溢出的情况(涉及到函数栈帧相关内容,后续我会出一篇博客单独分享滴~大家点个关注敬请期待呀!)。
其实,我们看一眼上面函数递归的过程也就能明白了:
我们会发现,过程中有许多重复冗余的计算过程,看着就累人...哦不对,累机~
连这么前面的第45个数都要被计算这么多遍了,很难想象最靠近边界条件的F(3)会被计算多少次,你好奇嘛?我也是,咱们一起来看看吧
1.5 庞大计算次数与反思
我们定义一个全局变量count,再在上面的Fibonacci斐波那契数函数中加入一个条件:当 n==3 时,计数变量count++
于是,我们的函数代码就变成了下面这样:
int Fibonacci(int n)
{
if (n == 1 || n == 2)
{
return 1;
}
else if (n == 3)
{
count++;
}
else {
return (Fibonacci(n - 1) + Fibonacci(n - 2));
}
}
再在主函数最后加上一个打印 count的值,运行完后便可得到这么一个可怕的数值:
如果我们要算出第40个数,那么F(3)就需被计算三千九百多万次!
当然,如果我们采用普通的迭代——循环方法求解,效率就会改善很多:
int Fibonacci(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n > 2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
由此我们也可直观地感受到,函数递归并不是万能的,有时候直接用循环便可快速高效地解决我们的问题,如何在二者间作出选择就需要我们结合实际情况来判断啦~
以上便是求解斐波那契数的所有内容啦,主要还是运用递归思想,从我们要求的第n个数开始,逐步往回“递”,求第 n-1 与第 n-2 个数的和,在n退到1,2两个数便往回传结果从而实现目标数字的求解。
十分感激你看到这里,如果本篇内容对你有所启发的话就麻烦点个赞吧(虔诚脸),你的点赞、收藏、关注都是对我莫大的鼓励~
后续还会根据这篇内容更新有关递归经典题目——青蛙跳台阶问题,敬请期待!
再次感谢你的观看,让我们下次再见!