一、什么是斐波那契數列
斐波那契數列,又稱黃金分割數列,指的是這樣一個數列:0、1、1、2、3、5、8、13、21、……在數學上,斐波納契數列以如下被以遞歸的方法定義:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*),斐波那契數列最初是為了計算兔子的出生數量而出現的,所以也叫“兔子數列”!
二、什么是遞歸
遞歸的本質其實程序的方法自身調用自身,在到達一個條件的時候停止調用(所以在用遞歸的時候一定要找好基准條件,否則就是一個列循環!)。
這是一個更正式的定義:
程序調用自身的編程技巧稱為遞歸( recursion)。
一個過程或函數在其定義或說明中有直接或間接調用自身的一種方法,它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計算,大大地減少了程序的代碼量。遞歸的能力在於用有限的語句來定義對象的無限集合。一般來說,遞歸需要有邊界條件、遞歸前進段和遞歸返回段。當邊界條件不滿足時,遞歸前進;當邊界條件滿足時,遞歸返回。
注意:
(1) 遞歸就是在過程或函數里調用自身;
(2) 在使用遞歸策略時,必須有一個明確的遞歸結束條件,稱為遞歸出口。
三、對應代碼的實現
有如題:用遞歸求第10個數,它等於前2數之和,如{1,1,2,3,5}
用遞歸的方法實現代碼如下:
public class Test { /* 斐波那契數列: 0、1、1、2、3、5、8 可以這樣理解 f0 = 0; f1 = 1; fn = f(n-1) + f(n - 2) (n >= 2) */ public static void main(String[] args) { System.out.println(f(5)); } public static int f(int n) { if (n == 1 || n == 2) { return 1; } else { return f(n - 1) + f(n - 2); } } }
這個程序很簡單,自己仔細想想就可以明白了!
非遞歸方法實現代碼:
public class Fab { /* 斐波那契數列,用循環的方式來寫 */ public static void main(String[] args) { System.out.println(funt(5)); } public static int funt(int index) { if(index == 1 || index == 2) { return 1; } int f1 = 0; int f2 = 1; int res = 0 ; /*在這里因為第一位是寫死的,所以會多算一次*/ for(int i=0; i<index -1 ;i++) { res = f1 + f2; f1 = f2; f2 = res; } return res; } }
注:所有遞歸都可以用相對應的循環代碼來進行對應的功能實現!
三、應用場景
在系統中,構造樹形結構(WBS模板樹、具體項目的WBS樹、項目群樹、省市縣樹形結構等)時用到了遞歸算法。就結構簡單的樹形結構而言,對性能的影響並不明顯,例如項目群樹,它的屬於一維的樹形結構,且采用遞歸算法的遞歸深度小於3。但是,對於復雜的樹形結構,采用遞歸算法實現時,響應速度普遍較慢,如WBS模板樹、具體項目的WBS樹以及省市縣樹形結構等,都是多維的,且遞歸深度不確定(至少大於3)。因此,在構造復雜的樹性結構時需要把遞歸算法轉換為非遞歸算法。除此之外,在其它復雜的遞歸算法中,也可以采用將遞歸算法轉換為非遞歸算法的方法,以提高算法的性能。
注:性能方面:(這個是我在網上看的大多數人的經驗來寫的自己並沒有實驗),我用到的遞歸主要是用在建立樹形菜單上面且深度沒有超過3級所以性能沒有很大的變化,網友說在構建樹形菜單的時候超過3級以后特別是數據比較多,性能就會出現明顯的低下!所以在性能出現低下的時候最好用對應的循環來實現最好!
