当前位置:网站首页>我的递归从不爆栈
我的递归从不爆栈
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)复杂度,就肯定不会爆栈了。
引用
边栏推荐
猜你喜欢

Security First: Tools You Need to Know to Implement DevSecOps Best Practices

Google Earth Engine APP—— 一个不用写代码可以直接下载相应区域的1984-2021年的GIF遥感影像动态图

MySQL索引

Taking advantage of cloud-network integration, e-Surfing Cloud has paved the way for digital transformation for government and enterprises

MySQL基本操作和基于MySQL基本操作的综合实例项目

Navicat 连接Oracle时提示oracle library is not loaded的问题解决

动力电池扩产潮,宁德时代遭围剿

腾讯架构师是如何解释:Redis高性能通信的原理(精华版)

今年上半年,我国公路建设总体形势持续向好

载20(S)-人参皂苷/细胞穿膜肽-单克隆抗体-载丝裂霉素白蛋白纳米微球的制备
随机推荐
打补丁的日子,比写代码的日子难熬多了
AI+医疗:使用神经网络进行医学影像识别分析
白话电子签章原理及风险
分布式 | dble 启动的时候做了什么之配置检测
百问百答第49期:极客有约——国内可观测领域SaaS产品的发展前景
蔚来杯2022牛客暑期多校训练营5 ABCDFGHK
究极异常处理逻辑——多层次异常的处理顺序
golang源码阅读(11)GO中各个目录的功能
0725-面试记录
H.265视频流媒体播放器EasyPlayer.js集成时报错“SourceBuffer ”如何解决?
Since September, China has granted zero-tariff treatment to 98% of tax items from 16 countries including Togo
ffmpeg编译后找不到libx264
shell中awk命令的if条件语句引入外置变量
ES: WeakSet
IDEA相关配置(特别完整)看完此篇就将所有的IDEA的相关配置都配置好了、设置鼠标滚轮修改字体大小、设置鼠标悬浮提示、设置主题、设置窗体及菜单的字体及字体大小、设置编辑区主题、通过插件更换主题
阿波罗 planning代码-modules\planning\lattice\trajectory_generation\PiecewiseBrakingTrajectoryGenerator类详解
谁抢走了华大基因的生意?
golang刷leetcode动态规划(9)不同路径 II
嵌入式Qt-做一个秒表
来亲自手搭一个ResNet18网络