通常地,對於java語言而言,普通的遞歸調用是在java虛擬機棧上完成的.假如a()是一個遞歸方法,那麼在其內部再調用本身的時候,假設爲a1(),那麼a1()方法變量表將建立在a()方法棧幀之上,從而造成了一個新的棧幀.所以容易發現,在遞歸思想中,遞歸簡化了問題的表達,但犧牲了虛擬機棧中的內存空間.java
public static int fib(int num){ if(num<2) return num; else return fib(num-2)+fib(num-1); }
public static int fib3(int n) { if (n < 2) return n; else { int pre = 0; int suf = 1; for (int i = 2; i <= n; i++) { int temp = suf; suf += pre; pre = temp; } return suf; } }
public class Main { public static void main(String[] args) { System.out.print(fib2(3, 0, 1)); } public static int fib2(int count, int pre, int result) { if (count == 1) return result; else return fib2(--count, result, result + pre); } }
public static void main(String[] args) { long time = new Date().getTime(); int num=40; System.out.println(fib(num)); System.out.println("普通遞歸調用用時:" + (new Date().getTime() - time) + "毫秒"); time = new Date().getTime(); System.out.println(fib2(num, 0, 1)); System.out.println("尾遞歸優化調用用時:" + (new Date().getTime() - time) + "毫秒"); time = new Date().getTime(); System.out.println(fib3(num)); System.out.println("for循環法調用用時:" + (new Date().getTime() - time) + "毫秒"); } //輸出 /* 102334155 普通遞歸調用用時:674毫秒 102334155 尾遞歸優化調用用時:0毫秒 102334155 for循環法調用用時:0毫秒 */
//count做爲計數,表示遞歸層次, //pre表明前一個值 //result 表示當前值 public static int fib2(int count, int pre, int result) { //層次減到1時返回計算結果 if (count == 1) return result; else{ //遞歸調用時,層次減1,前一項更新爲當前項,因此填result,第三個參數即實現了倒數第二個參數加倒數第一個參數. return fib2(--count, result, result + pre); } }