【C语言】求斐波那契(Fibonacci)数列通项(递归法、非递归法)

来源:互联网 发布:哈布斯堡 知乎 编辑:程序博客网 时间:2024/05/16 09:08

意大利的数学家列昂那多·斐波那契在1202年研究兔子产崽问题时发现了此数列.设一对大兔子每月生一对小兔子,每对新生兔在出生一个月后又下崽,假若兔子都不死亡.   问:一对兔子,一年能繁殖成多少对兔子?题中本质上有两类兔子:一类是能生殖的兔子,简称为大兔子;新生的兔子不能生殖,简称为小兔子;小兔子一个月就长成大兔子.求的是大兔子与小兔子的总和。


 月     份  ⅠⅡ  Ⅲ  Ⅳ  Ⅴ Ⅵ  Ⅶ  Ⅷ Ⅸ Ⅹ  Ⅺ  
大兔对数 
         13  21 34 55 89 144
小兔对数 
           13 21 34 55  89  到十二月时有大兔子144对,小兔子89对,共有兔子 144+89=233对从上表看出:

① 每月小兔对数=上月大兔对数。
②每月大兔对数等于上个月大兔对数与小兔对数之和.
 
     综合①②两点,我们就有:每月大兔对数等于前两个月大兔对数之和.


如果用 un 表示第 n 月的大兔对数,则有
un = un-1 + 
un-2,  n >2每月大兔对数un 排成数列为:1,1,2,3,5,8,13,21,34,55,89,144,        此数列称为斐波那契数列.


递归法:

使用公式f[n]=f[n-1]+f[n-2],依次递归计算,递归结束条件是f[1]=1,f[2]=1。

代码示例:

#include<iostream>using namespace std;long long Fib(int n){    if (n == 0)    {        return 0;    }    else if (n == 1)    {        return 1;    }    else if(n > 1)    {        return Fib(n - 1) + Fib(n - 2);    }    //return n > 1 ? Fib(n - 1) + Fib(n - 2) : n; //条件运算符简单,一行代码即可}void Test(){    int N = 0;    scanf("%d", &N);    int ret = Fib(N);    printf("%d\n", ret);}int main(){    Test();    system("pause");    return 0;}

但是,递归法解决此问题并非高效,下面我们看看非递归法。



非递归法:

迭代实现是最高效的,时间复杂度是n*1 = 0(n),空间复杂度是0(1)。

#include<iostream>using namespace std;long long Fib(int n){    if (n == 0)    {        return 0;    }    else if (n == 1)    {        return 1;    }    else if (n > 1)    {        int a = 1;        int b = 1;        int c = 1;        for (int i = 2; i < n; i++)        {            c = a + b;            a = b;            b = c;        }        return c;    }}void Test(){    int N = 0;    scanf("%d", &N);    int ret = Fib(N);    printf("%d\n", ret);}int main(){    Test();    system("pause");    return 0;}


本文出自 “Han Jing's Blog” 博客,请务必保留此出处http://10740184.blog.51cto.com/10730184/1755424

0 0
原创粉丝点击