1. 程式人生 > >JAVA學習入門篇_遞歸結構

JAVA學習入門篇_遞歸結構

img 程序 result 分享圖片 思想 als 強調 不執行 包括

遞歸結構

遞歸是一種常見的解決問題的方法,即把問題逐漸簡單化。遞歸的基本思想就是“自己調用自己”,一個使用遞歸技術的方法將會直接或者間接的調用自己。

? 利用遞歸可以用簡單的程序來解決一些復雜的問題。比如:斐波那契數列的計算、漢諾塔、快排等問題。

? 遞歸結構包括兩個部分:

? 1.定義遞歸頭。解答:什麽時候不調用自身方法。如果沒有頭,將陷入死循環,也就是遞歸的結束條件。

? 2.遞歸體。解答:什麽時候需要調用自身方法。

【示例3-22】遞歸:計算n!  

public class Test22 {
    public static void main(String[] args) {
        long d1 = System.currentTimeMillis();  
        System.out.printf("%d階乘的結果:%s%n", 10, factorial(10));
        long d2 = System.currentTimeMillis();
        System.out.printf("遞歸費時:%s%n", d2-d1);  //耗時:32ms
    }
    /** 求階乘的方法*/
    static long  factorial(int n){
        if(n==1){//遞歸頭
            return 1;
        }else{//遞歸體
            return n*factorial(n-1);//n! = n * (n-1)!
        }
    }
}

技術分享圖片

圖3-27 示例3-22運行效果圖

技術分享圖片

圖3-28 遞歸原理分析圖

遞歸的缺陷

? 簡單的程序是遞歸的優點之一。但是遞歸調用會占用大量的系統堆棧,內存耗用多,在遞歸調用層次多時速度要比循環慢的多,所以在使用遞歸時要慎重。

? 比如上面的遞歸耗時558ms。但是用普通循環的話快得多,如示例3-23所示。

使用循環求n

public class Test23 {
    public static void main(String[] args) {
        long d3 = System.currentTimeMillis();
        int a = 10;
        int result = 1;
        while (a > 1) {
            result *= a * (a - 1);// a* 
            a -= 2;
        }
        long d4 = System.currentTimeMillis();
        System.out.println(result);
        System.out.printf("普通循環費時:%s%n", d4 - d3);
    }
}

技術分享圖片

圖3-29 示例3-23運行效果圖

註意事項

? 任何能用遞歸解決的問題也能使用叠代解決。當遞歸方法可以更加自然地反映問題,並且易於理解和調試,並且不強調效率問題時,可以采用遞歸;

? 在要求高性能的情況下盡量避免使用遞歸,遞歸調用既花時間又耗內存。

總結

 1.從結構化程序設計角度出發,程序有三種結構:順序結構、選擇結構和循環結構

  2.選擇結構

  (1)if單選擇結構 if-else雙選擇結構 if-else if-else多選擇結構

  (2)switch多選擇結構

  3.多選擇結構與switch的關系:當布爾表達式是等值判斷的情況,可使用多重選擇結構或switch結構,如果布爾表達式區間判斷的情況,則只能使用多重選擇結構

   (1) 循環結構

   (2)當型:while與for

   (3)直到型:do-while

  4.while與do-while的區別,在布爾表達式的值為false時while的循環體一次也不執行,而do-while至少執行一次

  5.break可以在switch與循環結構中使用,而continue只能在循環結構中使用

  6.方法就是一段用來完成特定功能的代碼片段,類似於其它語言的函數

  7.方法的重載是指一個類中可以定義多個方法名相同,但參數不同的方法。 調用時,會根據不同的參數自動匹配對應的方法

  8.任何能用遞歸解決的問題也能使用叠代解決。在要求高性能的情況下盡量避免使用遞歸,遞歸調用既花時間又耗內存。

JAVA學習入門篇_遞歸結構