当前位置:网站首页>我的递归从不爆栈
我的递归从不爆栈
2022-08-02 17:42:00 【高级摸鱼工程师】
聊算法的时候,「递归」是避不开的一种技巧,因为很多算法其实会借助此技巧去实现。
那么问题来了,用不好递归会「爆栈」️️️ StackOverFlow
but ! 「尾递归」不会爆栈!
那么尾递归相比正常递归有什么特点呢?
- 尾调用函数本身,没有多余计算逻辑。
- 优化栈空间,从O(n)到O(1)
以 Python 为例,主要区分普通递归和尾递归对栈空间的使用:
def recsum(x):
if x == 1:
return x
else:
return x + recsum(x - 1)
调用recsum(5)为例,相应的栈空间变化如下:
recsum(5)
5 + recsum(4)
5 + (4 + recsum(3))
5 + (4 + (3 + recsum(2)))
5 + (4 + (3 + (2 + recsum(1))))
5 + (4 + (3 + (2 + 1)))
5 + (4 + (3 + 3))
5 + (4 + 6)
5 + 10
15
可观察,堆栈从左到右,增加到一个峰值后再计算从右到左缩小,这往往是我们不希望的。修改以上代码,可以成为尾递归:
def tailrecsum(x, running_total=0):
if x == 0:
return running_total
else:
return tailrecsum(x - 1, running_total + x)
对比后者尾递归对内存的消耗:
tailrecsum(5, 0)
tailrecsum(4, 5)
tailrecsum(3, 9)
tailrecsum(2, 12)
tailrecsum(1, 14)
tailrecsum(0, 15)
15
ps : tailrecsum(4, 5) 执行的时候,tailrecsum(5, 0) 在栈上其实就可以回收掉了。
可以看到尾递归相比普通递归,栈空间做到了O(1)的复杂度,也就起到了内存优化的作用。
那么因为是O(1)复杂度,就肯定不会爆栈了。
引用
边栏推荐
猜你喜欢
随机推荐
研发运营一体化(DevOps)能力成熟度模型
HDF驱动框架的API(1)
今年上半年,我国公路建设总体形势持续向好
如何生成随机数+原理详细分析
Wechat Gymnasium Appointment Mini Program Graduation Design Finished Works Mini Program Graduation Design Finished Work (6) Question Opening Reply PPT
IDEA相关配置(特别完整)看完此篇就将所有的IDEA的相关配置都配置好了、设置鼠标滚轮修改字体大小、设置鼠标悬浮提示、设置主题、设置窗体及菜单的字体及字体大小、设置编辑区主题、通过插件更换主题
H5网页播放器EasyPlayer.js播放器界面的加载效果无法消失是什么原因?
Go 语言快速入门指南: 介绍及安装
Dream weaving prompt information prompt box beautification
IReport常见问题及处理方法
在线文档Sheet技术解析
Playing in the cloud | The key technology of Tianyi cloud object storage ZOS high availability is revealed
MySQL命令(命令行方式,而非图形界面方式)
HDF驱动框架的API(2)
租房小程序自动定位城市
H.265视频流媒体播放器EasyPlayer.js集成时报错“SourceBuffer ”如何解决?
What is the difference between erp system and wms system
什么是SVN(Subversion)?
golang刷leetcode动态规划(10)编辑距离
Flink学习9:配置idea开发flink-Scala程序环境









