Java基础学习:java方法的递归讲解

1 篇文章 0 订阅

提到方法的递归调用,需要先说一下栈的存储概念。

  栈是一个先进后出的压入(push)和弹出(pop)式数据存储结构。若想获取到栈底的对象,就必须先将这个对象上面的所有的对象全部从栈中移除,否则无法获取栈底的对象。

  我们来看看程序中栈是如何工作的,当一个方法(调用者)调用另一个方法(被调用者)时,将会将调用者的参数和返回值一起压入到栈中,此时调用者方法处于栈顶的位置,当调用者执行到调用方法的语句时,此时调用者方法将不会继续执行,即将执行被调用者方法,那么被调用者就会与参数返回值一起压入到栈中,此时被调用者处于栈顶的位置,所以此时先执行被调用者方法。直到被调用者方法执行结束,所有的参数以及局部变量会随着方法的执行结束一起弹出栈空间,此时被调用者方法的返回值将会被带出方法,数据不会随着方法的出栈而消失,而是会落入到此时栈顶的方法中,所以方法的返回值是返回到方法的调用处

Java基础学习:java方法的递归讲解

 

  下图是以上代码执行过程中,栈空间中存储的变化:

Java基础学习:java方法的递归讲解

 

最近整理了一份覆盖一线大厂Java面试题总结+各知识点学习思维导+一份300页pdf文档的Java核心知识点总结!

想要领取这份PDF的伙伴 +V:BGM7756  回复【CSDN】即可免费领取PDF资料

方法的递归调用

  递归调用是一种特殊的嵌套调用,是某个方法直接或间接的调用自己,实际上相当于是循环执行功能代码。换句话说,就是可以使用方法递归调用完成的功能,同样也可以使用循环完成。

  方法递归调用的分类

  直接递归:现有fun方法,在fun方法中调用fun方法,这种调用方式称为直接递归调用。

  间接递归:现有fun1方法和fun2方法,在fun1方法中调用fun2方法,在fun2方法中调用fun1方法,实际并没有在fun1方法中直接调用自己,而是调用了fun2方法,间接的调用了fun1方法,这种调用方式称为间接递归调用。

  递归调用的案例

  案例:设计一个方法,使用循环计算一个整数的阶乘结果。

Java基础学习:java方法的递归讲解

 

  当然,这个案例也可以使用方法的递归调用来完成,关于这个问题使用递归调用完成时,与数学中的一类题目类似:

 

Java基础学习:java方法的递归讲解

 

  上图的数学问题,若想计算解集的话,需要将x的值带入到表达式中,但是对于x的不同取值范围,需要使用不同的表达式计算结果。对于这个数学问题的计算过程,在此我们就不再演示。

  若使用递归调用的方法计算一个整数的阶乘结果时,我们已知n的阶乘计算方法是从1开始乘一直乘到n为止,所以1的阶乘结果是1。那么计算n的阶乘,当n>1时,n的阶乘等于n乘n-1的阶乘;当n=1时,n的阶乘等于1。通过分析,请我们可以使用分支结果完成分析过程中的:当...则...,当...则...

  我们可以将递归调用写成一下格式的分段函数:

 

Java基础学习:java方法的递归讲解

 

  递归调用中的返回值

  由于方法的返回值返回到方法的调用处,所以方法递归调用返回时是一层一层的向外返回。

  我们都玩过欢乐球,欢乐球中灌了水,再将欢乐球放进一个盛水的小玻璃缸中,小玻璃缸放进一个大玻璃缸中,将欢乐球中捅破时,欢乐球中的水一定是进入到小玻璃缸中,而不是直接进入大玻璃缸中。

  下图是递归调用计算阶乘的返回值的图,返回值一定是一层一层向外返回,而不是最内层的返回整个方法结束。

Java基础学习:java方法的递归讲解

 

  方法压栈与方法递归

  以上叙述我们说过,一个方法在执行时,会压入栈中,而递归调用相当于多次调用同一个方法,那么递归几次,就会在栈中开辟几个相同大小的空间,所以使用递归调用时,比较好性能,我们可以通过循环来完成递归完成的功能。

最近整理了一份覆盖一线大厂Java面试题总结+各知识点学习思维导+一份300页pdf文档的Java核心知识点总结!

想要领取这份PDF的伙伴 +V:BGM7756  回复【CSDN】即可免费领取PDF资料

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
递归是一种重要的程序设计技巧,它允许函数或方法在其自身内部进行调用,以解决复杂的问题。Java递归程序设计的实现需要注意以下几个知识点: 1. 递归函数的定义 递归函数是一种函数,它在函数体内部调用自身。递归函数必须包含以下两个部分: * 基线条件:这是一种停止递归的条件。当满足基线条件时,递归将停止。 * 递归条件:这是递归函数继续调用自身的条件。递归条件必须包含能将问题规模缩小的逻辑。 例如,下面是一个计算阶乘的递归函数: ``` public static int factorial(int n) { if (n == 0) { // 基线条件 return 1; } else { // 递归条件 return n * factorial(n - 1); } } ``` 2. 递归调用的过程 递归调用是一个函数调用自身的过程。在递归调用时,每个函数调用都会创建一个新的函数栈帧,并将其推入函数调用栈。 在递归函数调用过程中,每个函数栈帧都会保存函数调用时的参数和局部变量。当递归函数满足基线条件时,函数调用栈开始弹出函数栈帧,直到所有函数栈帧都被弹出为止。 3. 递归程序设计的效率 递归程序设计可以使代码更加简洁,但使用不当可能会导致栈溢出等问题。因此,在编写递归程序时需要注意以下几点: * 确定基线条件和递归条件,以避免无限递归。 * 尽可能使用尾递归,以减少函数调用栈的深度。 * 避免使用过多的局部变量和参数,以减少函数栈帧的大小。 下面是一个使用递归函数求斐波那契数列的示例代码: ``` public static int fibonacci(int n) { if (n == 1 || n == 2) { // 基线条件 return 1; } else { // 递归条件 return fibonacci(n - 1) + fibonacci(n - 2); } } ``` 以上就是Java递归程序设计的基本知识点和示例代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值