11. Java 遞歸算法詳解以及迭代效率測試


遞歸算法

遞歸的基本思想是 “自己調用自己” 。

  1. 遞歸的基本思想:“自己調用自己”,一個使用遞歸技術的方法將會直接或間接的調用自己。
  2. 利用遞歸可以用簡單程序解決一些復雜問題。比如:斐波那契數列的計算、漢諾塔、快排等。
  3. 遞歸結構包括兩部分:
  • 定義遞歸頭。PS:如果沒有遞歸頭,將陷入死循環,也就是定義遞歸的結束條件。
  • 遞歸體。PS:什么時候需要調用自身方法。

遞歸缺陷:

遞歸調用會占用大量的系統堆棧,內存耗用多,在遞歸調用層次多時速度要比循環慢得多,所以使用遞歸時需慎重。

遞歸原理分析圖

使用遞歸計算 5! 階乘

代碼示例:簡單測試:自己調用自己的方法

  1. 一個方法里可以去調用其他方法
    2.自己調用自時,會一直調用,直到占滿系統資源拋出異常。
// 測試遞歸算法
public class TestRecursion01 {
    public static void main(String[] args) {
        a(3);
    }
    static void a(int c){
        System.out.println("a");
        // 一個方法里可以去調用其他方法
        b();
        // 自己調用自己:會一直調用,直到占滿系統資源拋出異常。
        a(3);
    }
    static void b(){
        System.out.println("b");
    }
}

代碼示例:使用遞歸計算 n!(對比下方循環效率)

  1. printf() 輸出函數作用:定義一些變量,用來格式化輸出。
  2. %n 作用是輸出時實現換行。%n是一種格式字符串,只能用到printf()的參數里。
  3. %n 是轉義字符,可以用於一切字符串。
// 使用遞歸計算 n!(對比循環效率)
public class TestRecursion {
    public static void main(String[] args) {
        // 記錄 開始 調用方法進行計算的時刻
        long d1 = System.currentTimeMillis();
        /**
         * printf() 輸出函數作用:定義一些變量,用來格式化輸出。
         * %n 作用是輸出時實現換行。%n是一種格式字符串,只能用到printf()的參數里。
         * %n 是轉義字符,可以用於一切字符串。
         * */
        System.out.printf("%d階乘的結果是:%s%n",10,factorial(10));
        // 記錄 結束 調用方法進行計算的時刻
        long d2 = System.currentTimeMillis();
        System.out.printf("遞歸消耗時間是:%s ms%n",d2 - d1); // 耗時: ms
    }
    // 求階乘的方法
    static long factorial(int n){
        if (n == 1) {// 遞歸頭
            return 1;
        }else{ // 遞歸體:factorial(n - 1) 在方法內反復調用自己,直到 n == 1
            return n * factorial(n - 1); // n! = n * (n - 1)!
        }
        // 1*2*3*4*…*9*10
    }
}

注意點

  1. 任何能用遞歸解決的問題也能使用迭代解決。
  2. 當遞歸方法可以更加自然地反映問題,並且易於理解和調試,並不強調效率問題時,可以采用遞歸。
  3. 在要求搞性能的情況下盡量避免使用遞歸,遞歸調用既花時間又耗內存。

代碼示例:使用循環計算 n!(對比遞歸效率)

// 使用循環求 n! (對比遞歸效率)
public class TestRecursion02 {
    public static void main(String[] args) {
        // 記錄 開始 調用方法進行計算的時刻
        long d3 = System.currentTimeMillis();
        int a = 10;
        int result = 1;
        while (a > 1){
            result *= a * (a-1);
            a -= 2;
        }
        // 記錄 結束 調用方法進行計算的時刻
        long d4 = System.currentTimeMillis();
        System.out.println("10! 階乘計算結果為:" + result);
        System.out.printf("計算消耗時間為:%s ms%n",d4 - d3);
    }
}

至此,遞歸算法知識點以及相關效率對比測試到此結束。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM