概述
斐波那契数列:1 1 2 3 5 8 13 21 34 55 89......
通过观察,我们不难发现,其规律为:从第三个数开始,前两个数的和等于后一个数。
基于此规律,下面将给出用递归来求斐波那契数和非递归求斐波那契数的方法,并比较这两种方法的优缺点。
首先讲讲递归的方法。
递归的方法
基于上述规律,我们可以得出以下公式:
Fib(n) = 1(n<=2), Fib(n)= Fib(n-2) + Fin(n-1) (n>2)
根据这个公式,我们很容易就转换成代码,请看:
#define _CRT_SECURE_NO_WARNINGS 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;
scanf("%d", &n);
int ret = Fib(n);
printf("%d", ret);
return 0;
}

当我们求第五个斐波那契数的时候,一切都很正常,运行结果也是正确的,请再看下面一段代码,我们换个更大的值输入,看看 结果如何。
#define _CRT_SECURE_NO_WARNINGS 1
#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 = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
printf("%d\n", count);
return 0;
}

当我输入50的时候,光标一直在闪动,但却迟迟算不出结果来,我们下面输入一个比50小的数来感受一下算不出来的原因。

可以看出,当计算第40个斐波那契数时就第三个斐波那契数就被重复计算了3900多万次,当输入50时,算不出结果也就显而易见,那就是程序效率太低,有大量重复计算。
迭代的方法求斐波那契数
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。重复执行一系列运算步骤,从前面的量依次求出后面的量的过程。此过程的每一次结果,都是由对前一次所得结果施行相同的运算步骤得到的。循环就是迭代的一种。
下面请看代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;//当n<=2时返回值c就是所求斐波那契数,因此不赋值为0
while (n>=3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("ret = %d\n", ret);
return 0;
}

当输入5是结果完全正确,虽然输入50时结果很明显是错误的(因为超出了int的范围),但是运行很快,效率较高。
两种方法的比较
递归的方法在实现时,仅仅需要几行代码就可以搞定,但是同时我们也看到了它的低效,此题用递归的方法做有很明显的不足,要慎用递归。至于迭代的方法,显然比较适合本题,虽然函数的实现较为复杂,但却是比较可靠的。

3027

被折叠的 条评论
为什么被折叠?



