• 类与对象(七)----递归


    递归是什么

    递归就是方法自己调用自己,每次调用时传入不同的变量。解决复杂问题,减少耦合代码

    递归内存分析

    现有以下代码

    public class DiGui{
    	public static void main(String[] args) {
    		T t = new T();
    		t.rePrint(4);
    		
    	}
    }
    class T{
    	public void rePrint(int n){
    		if (n>2) {
    			rePrint(n-1);
    		}
    		System.out.println("n="+n);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    编译输出是
    n=2
    n=3
    n=4
    那么为什么不是4 3 2 呢 因为在递归中当调用方法时会重新先开辟一个栈空间,优先运行调用方法的结构体,以此循环,当不调用新的方法时,再依次进行方法下方的语句。从而导致输出语句是从后往前输出
    内存示意图:
    在这里插入图片描述只有当上一个语句块中的语句执行完才会执行下方的语句 (调用方法 包括找个方法内的所有语句都要执行完,才会回到调用方法的下面继续执行)

    递归实现阶乘

    4的阶乘 = 1234 5的阶乘 = 1234*5

    public class DiGui{
    	public static void main(String[] args) {
    		T t = new T();
    		int num = t.rePrint(5);
    		System.out.println(num);
    		
    	}
    }
    class T{
    	public int rePrint(int n){
    		if (n == 1) {
    			return 1;
    		}else{
    			return rePrint(n-1)*n;
    		}
    		
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    运行操作:
    1.main方法栈实例化T
    2.调用rePrint方法 并传入实参5
    3.rePrint方法栈(1)带入实参5
    if (n == 1) { //5不等于1 进入else
    return 1;
    }else{
    return rePrint(n-1)n; // 再开辟栈空间rePrint(2)5-1=4 传入下一个栈空间的是4 这里n先不进行运算先将调用的方法执行完回头再计算
    }
    (3.2)rePrint(2):

    if (n == 1) { //4不等于1 进入else
    return 1;
    }else{
    return rePrint(n-1)n; //再开辟空间rePrint(3)4-1=3 传入下一个栈空间的是3 这里n先不进行运算先将调用的方法执行完回头再计算
    (3.3)rePrint(3):

    if (n == 1) { //3不等于1 进入else
    return 1;
    }else{
    return rePrint(n-1)n; //再开辟空间rePrint(4)3-1=2 传入下一个栈空间的是2 这里n先不进行运算先将调用的方法执行完回头再计算
    (3.4)rePrint(4):

    if (n == 1) { //2不等于1 进入else
    return 1;
    }else{
    return rePrint(n-1)n; //再开辟空间rePrint(5)2-1=1 传入下一个栈空间的是1 这里n先不进行运算先将调用的方法执行完回头再计算
    (3.5)rePrint(5):

    if (n == 1) { //1等于1 进入if语句
    return 1; //返回值为1
    }else{
    return rePrint(n-1)*n;
    (3.6) rePrint(5)的返回值为1 带入rePrint(4) *n rePrint(4)的n是2所以是1X2 = 2 所以 rePrint(4)的返回值是1X2
    rePrint(4)的返回值为1x2 带入rePrint(3) *n rePrint(3)的n是3所以是1X2X3 所以 rePrint(3)的返回值为1X2X3
    rePrint(3)的返回值为1x2x3带入rePrint(2) *n rePrint(2)的n是4所以是1X2X3X4 所以 rePrint(2)的返回值为1X2X3X4
    rePrint(2)的返回值为1x2x3带入rePrint(1) *n rePrint(1)的n是5所以是1X2X3X4X5 所以 rePrint(1)的返回值为1X2X3X4X5
    4.rePrint方法最终返回1X2X3X4X5 结果为120 再到main栈 传给num变量 最后输出 num = 120

    内存图:
    在这里插入图片描述

    递归注意事项

    1-执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
    2-方法的局部变量是独立的,不会相互影响,比如n变量
    3-如果方法中使用的是引用类型变量(数组,对象),就会共享该引用类型的数据
    4-递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowErro,栈溢出
    5-当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕

  • 相关阅读:
    提升MODBUS-RTU通信数据刷新速度的常用方法
    Selenium UI 自动化
    7-4链表去重
    【稳定性】秘密武器--功能开关技术
    SpringMVC之JSON数据返回&异常处理机制
    第五章:java构造方法与对象创建
    轻松理解 Transformers(1):Input部分
    RISC Zero zkVM性能指标
    政安晨:【深度学习神经网络基础】(八)—— 神经网络评估回归与模拟退火训练
    rk3568 Android 11在系统怎样执行命令获取SN号
  • 原文地址:https://blog.csdn.net/WINorYU/article/details/126731967