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

php弱类型-攻防世界lottery

golang学习之七:并发编程基础(goroutine、channel、select)

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

灵动微电子发布低功耗 MM32L0130 系列 MCU 产品

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

用函数递归的方法解决汉诺塔问题

Mini Program Graduation Works WeChat Gymnasium Reservation Mini Program Graduation Design Finished Product (8) Graduation Design Thesis Template

基于HDF的LED驱动程序开发(1)

租房小程序自动定位城市

The days of patching are more difficult than the days of writing code
随机推荐
golang源码分析(3):thrift
阿里云关系型数据库RDS是干嘛额?
Mysql和Redis如何保证数据一致性
Smart Microelectronics Releases Low-Power MM32L0130 Series MCU Products
HDF驱动框架的API(1)
H5网页播放器EasyPlayer.js播放器界面的加载效果无法消失是什么原因?
百问百答第49期:极客有约——国内可观测领域SaaS产品的发展前景
IReport常见问题及处理方法
Redis总结_实战篇
H.265视频流媒体播放器EasyPlayer.js集成时报错“SourceBuffer ”如何解决?
搭建属于自己的知识库(Wikijs)
54.【system系统互动函数大总结】
方法的使用
Google Earth Engine APP—— 一个不用写代码可以直接下载相应区域的1984-2021年的GIF遥感影像动态图
9月起中国给予多哥等16国98%税目产品零关税待遇
Playing in the cloud | The key technology of Tianyi cloud object storage ZOS high availability is revealed
租房小程序自动定位城市
谁抢走了华大基因的生意?
POE交换机全方位解读(下)
golang源码分析(7):chan