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

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

【秒杀办法】根据二叉树的先序遍历、中序遍历、后序遍历快速创建二叉树

How a "cloud" can bring about new changes in the industry

织梦自定义表单添加全选和全不选功能按钮

年轻人接棒大妈,金价跌回“4字头”,七夕迎黄金消费小热潮

有关代购系统搭建的那点事

小程序毕设作品之微信体育馆预约小程序毕业设计成品(7)中期检查报告

Wechat Gymnasium Appointment Mini Program Graduation Design Finished Work (5) Task Book

二舅“反转”了?

文件上传很难搞?10分钟带你学会阿里云OSS对象存储
随机推荐
每日优鲜倒了,叮咚买菜的春天在哪?
mysql四种隔离级别
E-Surfing Cloud 4.0 Distributed Cloud Enables Digital Transformation of Thousands of Industries
redis总结_分布式缓存
【秒杀办法】根据二叉树的先序遍历、中序遍历、后序遍历快速创建二叉树
「全球数字经济大会」登陆 N 世界,融云提供通信云服务支持
KunlunBase 1.0 发布了!
再获权威认证!马上消费安逸花APP通过中国信通院“金融APP人脸识别安全能力评测”
golang刷leetcode 经典(6) 实现跳表
Wechat Gymnasium Appointment Mini Program Graduation Design Finished Works Mini Program Graduation Design Finished Work (6) Question Opening Reply PPT
golang源码分析(2):Golang context 包
How a "cloud" can bring about new changes in the industry
今年上半年,我国公路建设总体形势持续向好
小程序毕设作品之微信体育馆预约小程序毕业设计成品(7)中期检查报告
新特性解读 | MySQL 8.0 GIPK 不可见主键
golang源码分析(9)调度
发挥云网融合优势,天翼云为政企铺设数字化转型跑道
潮玩的“第二春”,在哪?
一文搞懂│php 中的 DI 依赖注入
cpolar应用实例之多设备数据采集