1.简述

  • A方法调用B方法,我们很容易理解
  • 递归就是:A方法调用A方法!就是自己调用自己
  • 利用递归可以用简单的程序来解决一些复杂的问题,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合
  • 递归结构包含两个部分
    • 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环
    • 递归体:什么时候需要调用自身方法
  • 实际应用中建议能不用递归就不用递归
  • 一些计算量不大的计算可以用递归,计算量较大的需要用其他算法

2.示例:

①简单的阶乘Demo

package com.xf2021.www;
import java.util.Scanner;
public class Demo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入阶乘边界:");
        String x=scanner.nextLine();
        long sum=test(Long.parseLong(x));
        System.out.println(x+"的阶乘为"+sum);
    }
    public static long test(long a ){
        if(a==0) {
            System.out.println("输入错误");
        }if(a==1) {
            return 1;
        }else{
            return a*test(a-1);
        }

    }
}

:因为阶乘最后得到的数会比较大,所以上述案例中所有用到的变量都定义为了Long类型。其次加入了a=0情况的判断,避免在输入0时发生栈溢出

②运行原理解析

解析之前先上两张图帮助理解:

个人理解:在上述递归实例中,当a≠1时,程序不断调用自身,返回的结果层层嵌套,直到能够返回一个确定的数值,个人感觉递归可以正向看也可以逆向看,我们解析一下上述阶乘实例在a=6时的运算情况:

如果正向来看:

  1. return 6*test(5)
  2. return 6*5*test(4)
  3. return 6*5*4*test(3)
  4. return 6*5*4*3*test(2)
  5. return 6*5*4*3*2*test(1) 递归到达边界
  6. return 6*5*4*3*2*1

如果逆向来看

  1. return 1; 递归到达边界,将值返回给上一层的test(2)
  2. return [2*test(1)] ⇔ tset(2)
  3. return [3*test(2)] ⇔tset(3)
  4. return [4*test(3)] ⇔tset(4)
  5. return [5*test(4)] ⇔tset(5)
  6. return [6*test(5)] ⇔tset(6)

:这里加上[ ]是为了方便说明中括号里面的东西等价于右边的东西,便于理解,实际操作中return后没有中括号

缩略图:


You got to put the past behind you before you can move on.