递归思想之---斐波拉契数列

 

斐波那契数列中的递归思想

 

  如果上述的分析都明白了,那就说明你已掌握了递归,但为了加深对递归的理解,我们再来看一个思考题(来自程序员的数学思考题),题目是这样的,假如动物中有一种特殊的种类,它出生2天后就开始以每天1只的速度繁殖后代。假设第1天,有1只这样的动物(该动物刚出生,从第3天开始繁殖后代)。那么到第11天,共有多少只呢?

 

我们先来按一般顺序思考,先不要考虑第11天,先从第1天开始,看能不能找出规律:
【第1天】只有1只动物
【第2天】只有1只动物,还没有繁殖后代,总量为1
【第3天】第1天的1只动物,繁殖1个后代,总量为2
【第4天】第1天的1只动物又繁殖1只,其他还没繁殖,总量为3
【第5天】第1天和第3天出生的动物又繁殖1个后代,其他没有繁殖,总量为5
【第n天】.....

 第1天 ------1
 第2天 ------1
 第3天 ------2 = 1 + 1
 第4天 ------3 = 1 + 2
 第5天 ------5 = 2 + 3 
 第6天 ------8 = 3 + 5
 第7天 ------13 = 5 + 8

 

   这个过程中貌似没发现什么规律,但我们发现从第3天开始动物的数量似乎前两天的总和,也就是第3天,是第1天的动物数量加上第2天的动物数量,而第4天则是第2天和第3天的动物数量的和。这样的话我们可以归纳一下,不去直接想”第n天有多少只动物“而是如下思考:

 

  • 第n-1天出生的动物,在第n天还存活着。
  • 第n-2天以前出生的动物,在第n天繁殖了后代

 

  因此可以总结出递推公式,假设在第n天时,第n-1天以前繁殖的动物都活着,并且第n-2天以前出生的动物会繁殖1个后代,设第n天的动物总数为F(n),则有:F(n)=F(n-1)+F(n-2) 其中 n>=3,如下图所示 

注意为了让F(2)=F(1)+F(0)成立,定义F(0)=0,而F(1)则依然为1,因此有如下公式: 

我们来验证这个递推公式是否符合递归条件

 

  • ①边界条件:至少有一条初始定义是非递归的,F(0)=0;F(1)=1。
  • ②递归通式:由已知函数值逐步计算出未知函数值,F(0)=0;F(1)=1,可以推算出F(2)=1,最终也可以推算F(n)的结束。

 

显然两个条件都符合,说明该通用公式可以在有限的次数内运算完成并达到边界条件得出结果,因此我们可以利用递推公式求出第11天的动物的数量:

 

F(0)=0
F(1)=1
F(2)=F(0)+F(1)=1
F(3)=F(2)+F(1)=2
F(4)=F(3)+F(2)=3
F(5)=F(4)+F(3)=5
F(6)=F(5)+F(4)=8
F(7)=F(6)+F(5)=13
F(8)=F(7)+F(6)=21
F(9)=F(8)+F(7)=34
F(10)=F(9)+F(8)=55
F(11)=F(10)+F(9)=89

也就是说第11天的动物总数为89只

 

在这个问题中出现的数列就是著名的斐波那契数列,是由数学家斐波那契发现的,由此得名斐波那契数列。

 

0 ,1 ,1 ,2 ,3 ,5 ,8,13 ,21 ,34 ,55 ,89 ,…

 

  到此我们也就知道斐波那契数列同样是用递归定义的,前面我们将求解第n天的动物数量分解为求第n-1天和第n-2天以前的动物繁殖后代数量,从把复杂的问题分解为较为简单的同类问题,而不去纠结第n天到此有多少只动物的问题,最终发现求解的规律,并通过递推公式求得第n天的结果,这个过程再次体现了递归的思维方式。既然斐波那契数列是递归思维的产物,那么也可以通过程序的递归算法来求解,接下来我们就看看如何使用程序中的递归算法来实现斐波那契数列。

 

斐波那契数列的递归程序实现

实现代码比较简单就不过多分析了,代码如下:

package com.zejian.structures.recursion;

/**
 * Created by zejian on 2016/12/11.
 * Blog : http://blog.csdn.net/javazejian [原文地址,请尊重原创]
 * 斐波那契数列的实现
 */
public class Fibonacci  {

    /**
     * 斐波那契数列的实现
     * 0,1,1,2,3,5,8,13,21......
     * @param day
     */
    public long fibonacci(int day){

        if(day==0){ //F(0)=0
            return 0;
        }else if (day==1||day==2){//F(1)=1
            return 1;
        }else {
           return fibonacci(day-1)+fibonacci(day-2); //F(n)=F(n-1)+F(n-2)
        }
    }

    /**
     * 更为简洁的写法
     * @param day
     * @return
     */
    public long fib(int day) {
        return day== 0 ? 0 : (day== 1 || day==2 ? 1 : fib(day - 1) + fib(day - 2));
    }

    //测试
    public static void main(String[] args){
        Fibonacci fibonacci=new Fibonacci();
        System.out.println("第11天动物数量为:"+ fibonacci.fib(11));
        System.out.println("第11天动物数量为:"+ fibonacci.fibonacci(11));
    }
}
原文地址:https://www.cnblogs.com/Darkqueen/p/9517780.html