1. 定义:
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、55、...... 这个数列从第3项开始,每一项都等于前两项之和。
2. 求第n个斐波那契数的方法:
(1)递归
#include<stdio.h>
int Fib(int n)
{
if (n <= 2)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
int n = 0;
printf("input n: ");
scanf("%d", &n);
printf("%d\n",Fib(n));
return 0;
}
我们输入50,看一下第50个斐波那契数是什么
可以看见,光标一直在闪,说明程序是一直在执行的状态,但是没有输出结果,这是为什么呢?
可见,重复计算的数有很多,是个不小的工程量,我们可以计算一下某个斐波那契数被重复计算的次数
统计一下计算第40个斐波那契数时第3个斐波那契数被重复计算的次数(代码如下):
//递归法
#include<stdio.h>
int count = 0;//全局变量
int Fib(int n)
{
//统计的是 第3个斐波那契数被重复计算的次数
if (3 == n)
{
count++;
}
if (n <= 2)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
int n = 0;
printf("input n: ");
scanf("%d", &n);
printf("%d\n",Fib(n));
printf("count= %d\n", count);
return 0;
}
由此可见,计算机的计算量非常大,时间复杂度和空间复杂度都极高,很容易造成栈溢出和超时。所以这里使用递归显然不是一个明智的选择。
扫描二维码关注公众号,回复:
15271102 查看本文章
(2)迭代
//迭代法
#include<stdio.h>
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n>2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
printf("input n: ");
scanf("%d", &n);
printf("%d\n",Fib(n));
return 0;
}
循环迭代方法的效率大大高于递归,只是相比于递归代码可读性稍微差一些。
3. 提示:
(1)许多问题是以递归的形式进行解释的,这只是因为它们比非递归的形式更为清晰。
(2)但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差一些。
(3)当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时的开销。