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


    递归是什么

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

    递归内存分析

    现有以下代码

    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,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕

  • 相关阅读:
    尊嘟假嘟?三行代码提升接口性能600倍
    如何搭建一个 websocket
    设计模式:适配器模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)
    Tensorflow-GPU工具包了解和详细安装方法
    十大排序算法(C语言)
    数学建模、统计建模、计量建模整体框架的理解以及建模的步骤
    rabbitmq 保姆级安装教程
    Go学习第九章——面向“对象”编程(三大特性与接口和断言)
    如何从代码层提高产品质量
    艺术与科技的狂欢,阿那亚2022砂之盒沉浸艺术季
  • 原文地址:https://blog.csdn.net/WINorYU/article/details/126731967