1. 程式人生 > >斐波那契數列--遞迴與非遞迴實現

斐波那契數列--遞迴與非遞迴實現

初識斐波那契數列:
斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:0,1、1、2、3、5、8、13、21、34、……在數學上,斐波納契數列以如下被以遞迴的方法定義:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)。
程式碼實現1—遞迴:

public class FibSeq{
    public static int fibSeq(int n){
        if(n<0
){ throw new IllegalArgumentException("the param is less than 0"); } if(n==0) return 0; if(n==1) return 1; return fibSeq(n-1);+fibSeq(n-2); } public static void main(String[] args) { //測試前10個 for(int i=0;i<10;i++){ System.out
.print(fibSeq(i)+" "); } } }

結果:
這裡寫圖片描述
程式碼實現1—普通迴圈:

public class FibSeq{
    public static int FeiBo1(int n){
        if(n<0){
            throw new IllegalArgumentException("the param is less than 0");             
        }
        if(n==0||n==1){
            return n;
        }
        /*int []res={0,1};
        if(n<2)
            return res[n];*/
int result=0; int fb0=0; int fb1=1; for(int i=2;i<=n;i++){ result=fb1+fb0; fb0=fb1;//先把下一個元素賦值給下下個元素,如果先把result賦值給下一個元素fb1, //則會將fb1覆蓋為result,當fb1在賦值給fb0時此時的fb0仍然是result的值 fb1=result; } return result; } public static void main(String[] args) { //測試前10個 for(int i=0;i<10;i++){ System.out.print(FeiBo1(i)+" "); } }

結果:
非遞迴實現
總結:
從程式碼量來看遞迴實現要簡單的多,但隨著數量n的增加,遞迴實現的時間複雜度也會隨著指數級增加,這是因為遞迴實現不斷的呼叫自己的字方法,中間會存在大量重複的元素,例如f(9)=f(8)+f(7),f(8)=f(7)+f(6),這兩個遞迴下來就會產生相同的f(7),當f(7)繼續呼叫時(f(7)=f(5)+f(6)),都會同時呼叫f(6)+f(5),,當n很大時,會產生大量的重複元素,繼而會產生大量的重複的方法呼叫,而每一次方法的呼叫虛擬機器都會在記憶體棧中重新分配空間以儲存引數、返回地址和臨時變數,而每個棧的容量是有限的,當遞迴呼叫層級太多時,會產生棧溢位,所以對於測試n=10,100,500,1000時普通迴圈的時間消耗要明顯小於遞迴實現。對於n很大時應該採用普通迴圈來計算斐波那契數列的值。