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