Java中遞歸和循環的優劣
阿新 • • 發佈:2019-03-10
static all 清晰 package 使用 出現 png 部分 過程 2、遞歸體:即什麽時候需要調用自身方法。
好了,廢話不多說,直接來擼代碼(計算階乘的方法)。
介紹:
你用你手中的鑰匙打開一扇門,結果去發現前方還有一扇門,緊接著你又用鑰匙打開了這扇門,然後你又看到一扇門......但是當你開到一扇門時,發現前方是一堵墻無路可走了,你選擇原路返回--這就是遞歸。
但是如果你打開一扇門後,同樣發現前方也有一扇門,緊接著你又打開下一扇門.....但是卻一直沒有碰到盡頭--這就是循環。
簡單來說:循環是有去無回,而遞歸是有去有回(因為存在終止條件)。
循環:當滿足某一條件時反復執行某一操作(循環體)。
遞歸:在一個方法內部對自身進行調用的方法。
遞歸結構包括兩個部分:
1、遞歸頭:即什麽時候不調用自身方法,也就是遞歸的結束條件。如果沒有遞歸頭,程序將陷入死循環。
好了,廢話不多說,直接來擼代碼(計算階乘的方法)。
package com.bjwyj.method; /** * 遞歸和循環的比較 * @author 吳永吉 * */ public class TestRecursion { public static void main(String[] args) { //以下調用System下的currentTimeMillis()方法只是為了說明遞歸調用比循環調用更耗時 long l1 = System.currentTimeMillis(); System.out.println(factorial(5)); long l2 = System.currentTimeMillis(); System.out.println("遞歸計算階乘耗時:"+(l2-l1)); System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"); long time1 = System.currentTimeMillis(); System.out.println(factorialLoop(5)); long time2 = System.currentTimeMillis(); System.out.println("循環計算階乘耗時:"+(time2-time1)); } //使用遞歸定義計算階乘的方法 public static long factorial(int num) { if(num==1) { //遞歸頭 return 1; }else { return num*factorial(num-1); //遞歸體 } } //使用循環定義計算階乘的方法 public static long factorialLoop(int n) { int result = 1; //接收計算結果 while(n>1) { result *= n*(n-1); //實現計算結果的累乘操作 n -= 2; //每次減去2,實現數字的叠代操作 } return result; } }
執行結果:
120 遞歸計算階乘耗時:1 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 120 循環計算階乘耗時:0
由結果可以看出,使用遞歸算法比使用循環算法更耗時。
為了更好地比較遞歸算法的優劣,上述采用while循環與遞歸算法進行對比。
先來分析上述遞歸方法的執行過程,如下圖:
循環方法的執行過程,如下圖:
這裏為了看起來清晰,只是簡單地畫出了棧內存中的執行過程(這樣畫更便於理解)。
總結:
棧,主要是用來存放棧幀的,每執行一個方法就會出現壓棧操作,所以采用遞歸的時候產生的棧幀比較多,遞歸就會影響到內存,非常消耗內存。而使用循環就執行了一個方法,壓入棧幀一次,只存在一個棧幀,所以比較節省內存。
Java中遞歸和循環的優劣