递归、调用栈及尾递归

 我来答
黑科技1718
2022-06-16 · TA获得超过5900个赞
知道小有建树答主
回答量:433
采纳率:97%
帮助的人:82.8万
展开全部

无论是否递归调用,当在一个函数(外层函数)的运行期间调用另一个函数(被调用函数,即内层函数)时,在运行被调用函数之前,系统需要先完成3个操作,即:

从被调函数返回调用函数(外层函数)之前,系统还要完成3个操作,即:

当有多个函数构成嵌套调用时,按照"后调用先返回"的原则,上述函数之间的信息传递和控制转移必须通过"栈"来实现,每当调用一个函数时,就在栈顶为它分配一个存储区,每当退出一个函数时,就释放它的存储区,当前正在运行的函数的数据区必在栈顶。 递归函数 的运行过程类似于多个函数的嵌套调用,只是调用和被调用函数是同一个函数。

函数调用时,需要在栈中分配新的帧,将 返回地址 , 调用参数 和 局部变量 入栈。所以递归调用越深,占用的栈空间越多。

为了解决递归的开销大问题,使用尾递归优化,具体分两步:

使用尾递归的好处:因为进入下一层函数不再需要参考外层函数的信息,因此没必要保存外层函数的栈信息,递归需要用的stack只有目前这层被调用函数的,因此避免了栈溢出风险。
一些语言提供了尾递归优化特性,当识别出使用了尾递归时,会相应地只保留当前层函数的stack,节省内存,不会发生stackOverflowException调用栈溢出。

注意:
JVM缺乏尾调用指令,java编译器对尾递归的优化未实现,所以在java中尽量避免过深的递归调用,如果需要使用递归,建议优化成迭代式。
*

尾递归就是操作的最后一步是调用自身的递归。注意,尾递归的判断标准是函数运行 最后一步 是否调用自身,而不是是否在函数的最后一行调用自身。
这个不是尾递归:

这个是尾递归:

参考:
[1]. 什么是尾递归
[2]. 尾调用优化
[3]. 栈是如何实现递归的:递归与栈一些不得不说的事
[4]. stack 的三种含义

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式