【Java】递归

目录

  1.递归的概念

 2.递归执行过程分析

3.关于"调用栈"

4.代码示例

4.1按顺序打印一个数字的每一位(例如1234打印出1  2   3  4)

4.2递归求1+2+3+...+10

4.3写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19

4.4求斐波那契数列的第N项(注意:这个递归方法如果求较大的项目时,会有大量的重复计算,如果使用循环,效率会高很多)

5.小结


  1.递归的概念

    当一个方法在执行过程中调用它本身,就称之为“递归”。

递归需要一个结束条件,然后也要有一个递归公式。

例如,我们求N!

结束条件:N=1的时候,N!为1,这个条件是递归的结束条件

递归公式:求N!,直接不好求,可以把问题转化成N!=>N*(N-1)!

代码示例:递归求N的阶乘

public class Test {

    public static void main(String[] args) {

        int n = factor(5); //调用递归函数并将n=5的值传进去 再把返回值存储到变量a中
        System.out.println("n=" + n);

    }
        public static int factor(int a){  //递归方法
            if(a==1){
                return 1;
            }else
                return a*factor(a-1);

    }
}

 2.递归执行过程分析

  递归的执行过程不太好理解,想要理解清楚递归,必须先理解“方法的执行过程”,尤其是“方法执行结束之后,回到调用位置继续往下执行。

我们把刚刚讲的N的阶乘这个递归方法来加上日志

public static void main(String[] args) {
int n = 5;
int ret = factor(n);
System.out.println("ret = " + ret);
}
public static int factor(int n) {
System.out.println("函数开始, n = " + n);
if (n == 1) {
System.out.println("函数结束, n = 1 ret = 1");
return 1;
}
int ret = n * factor(n - 1);
System.out.println("函数结束, n = " + n + " ret = " + ret);
return ret;
}
// 执行结果
函数开始, n = 5
函数开始, n = 4
函数开始, n = 3
函数开始, n = 2
函数开始, n = 1
函数结束, n = 1 ret = 1
函数结束, n = 2 ret = 2
函数结束, n = 3 ret = 6
函数结束, n = 4 ret = 24
函数结束, n = 5 ret = 120
ret = 120

 可见,递归方法顾名思义,既要有递的过程,也要有归的过程。当往下递的时候,会逐步到方法的结束条件,然后在往回递。

3.关于"调用栈"

  方法调用的时候,会有一个“栈”,这样的内存空间描述当前的调用关系,称为调用栈,每一次方法的调用就称为一个“栈帧”,每个栈帧包含了这次调用的参数是哪些,返回到哪些继续执行等信息。


4.代码示例

4.1按顺序打印一个数字的每一位(例如1234打印出1  2   3  4)

public  static void printf(int num){
        if(num>9) {
            printf(num / 10);
        }
        System.out.println(num%10);
    }

4.2递归求1+2+3+...+10

public static int sum(int num) {
if (num == 1) {
return 1;
}
return num + sum(num - 1);
}

4.3写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19

public static int sum(int num) {
if (num < 10) {
return num;
}
return num % 10 + sum(num / 10);
}

4.4求斐波那契数列的第N项(注意:这个递归方法如果求较大的项目时,会有大量的重复计算,如果使用循环,效率会高很多)

public static int fib(int n) {
if (n == 1 || n == 2) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}

5.小结

递归是一种重要的编程解决问题方式,有一些问题天然就是用递归方式来定义的(例如,斐波那契数列,二叉树等),此时使用递归来解就很容易。

如果有一些问题用递归和非递归(循环)都可以解决,那么更推荐使用循环,相比于递归,非递归程序运行会更加高效。因为递归会不断的调用方法,在栈上开启新的空间,可能还会有大量重复计算。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王尔政

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值