您的位置:首页 > 编程语言 > Python开发

Python尾递归

2016-10-06 15:13 169 查看
Python并不支持尾递归优化,我们只是使用其语法来描述这个概念。


尾递归就是操作的最后一步是调用自身的递归。它和一般的递归不同在对内存的占用,普通递归创建stack累积而后计算收缩,尾递归只会占用恒量的内存(和迭代一样)。

我们看一个对比:

普通递归

def recsum(x):
if x == 1:
return x
else:
return x + recsum(x - 1)


调用
recsum(5)
,Python调试器中发生如下状况:

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


这个曲线就代表内存占用大小的峰值,从左到右,达到顶峰,再从右到左收缩。而我们通常不希望这样的事情发生,所以使用迭代,只占据常量stack space(更新这个栈!而非扩展它)。

尾递归

def tailrecsum(x, running_total=0):
if x == 0:
return running_total
else:
return tailrecsum(x - 1, running_total + x)


调用
tailrecsum(5)
,Python调试器中发生如下状况:

tailrecsum(5, 0)
tailrecsum(4, 5)
tailrecsum(3, 9)
tailrecsum(2, 12)
tailrecsum(1, 14)
tailrecsum(0, 15)
15


观察到,
tailrecsum(x, y)
中形式变量
y
的实际变量值是不断更新的,对比普通递归就很清楚,后者每个
recsum()
调用中
y
值不变,仅在层级上加深。所以,尾递归是把变化的参数传递给递归函数的变量了。

有些编译器会把尾递归优化成循环,上面的例子用循环表述:

for i in range(6):
sum += i


Ref

https://www.zhihu.com/question/20761771/answer/19996299

https://zh.wikipedia.org/wiki/%E5%B0%BE%E8%B0%83%E7%94%A8
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: