首页 > 其他 > 详细

斐波那契(Fibonacci)数列的递归和非递归实现

时间:2015-09-26 22:24:17      阅读:239      评论:0      收藏:0      [点我收藏+]

 

  题目:斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……。在数学上,斐波纳契数列以如下被以递归的方法定义:

              F(0)=0F(1)=1F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)

 

  源码(递归算法)

long Fibonacci(long n)                          //递归算法
{
    if(n<=1)    return n;                       //终止递归的条件
    else return Fibonacci(n-1) + Fibonacci(n-2);//递归步骤
}

  

  分析

  这个Fibonacci的递归实现,每次递归调用都触发另外两个递归,而这两个递归在调用的时候每个都还要触发两外的两个递归调用,再接下去的调用也是如此。现在,我们知道,这个冗余的递归调用是以几何级数增长的。例如,在递归计算Fibonacci(10)时,Fibonacci(3)的值被计算了21次。而在递归计算Fibonacci(30),这个调用的次数是骇人的317811次!这些个计算实际上只有一次是必要的,其余的纯属浪费!

  下面的程序使用一个简单循环迭代来代替递归,这个非递归的形式不如上文给出的递归简单,也不太符合Fibonacci的递归定义,但是,它的效率提高了几十万倍!

 

  源码(非递归/迭代算法)

//计算斐波那契数列的非递归算法(迭代)
long Fibonacci(long n)
{
    int i;
    if(n<=1)    return n;                                //Fib(0)或Fib(1)的情况
    long FibCurrent , FibTwoBack = 0 , FibOneBeck = 1;   //用数组保存程序更简洁,但不能明显的看出迭代的思想
    for(i=2 ; i<=n ; i++)                                //n≥2的情况
    {
        FibCurrent = FibOneBeck + FibTwoBack;            //计算Fib(i)=Fib(i-1)+Fib(i-2)
        /* 下面的保存顺序不能对调 */
        FibTwoBack = FibOneBeck;                        //保存Fib(i-1)作为下趟的Fib(i-2)
        FibOneBeck = FibCurrent;                        //保存Fib(i)作为下趟的Fib(i-1)
                            
    }
    return FibCurrent;
}

 

  所以,本文的结论就是,当你使用递归实现一个函数之前,先问问自己使用递归的好处是否抵得上它所要付出的代价。当然,编程的时候,无论什么实现方式,我们都应该问问自己这个问题。

 

斐波那契(Fibonacci)数列的递归和非递归实现

原文:http://www.cnblogs.com/eniac12/p/4841320.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!