[英]recursive stack overflow in fibonacci function
我试图理解递归函数的堆栈溢出机制。 所以我用了这个斐波那契函数:
def fib(n):
if n==1 or n==2:
return 1
return fib(n-1)+fib(n-2)
print (fib(555))
当我尝试使用此函数来计算fibo(999)时,我遇到了RuntimeError:在比较中超过了最大递归深度,但是当我尝试计算fibo(555)时,python不会打印任何运行时错误,但仍然有效
我知道python中的默认递归deeptHs是1000,但我并不理解为什么当我尝试查找fibo时python不会打印运行时错误(555)
全民THK'X
可能是对堆栈深度的限制而不是对递归调用的数量的限制,并且在第一次调用fib()
之前,您可能已经用完了某些堆栈深度。
使用fib(555)
,您只会添加 555
堆栈帧,而不是555 + 554
。 这是因为计算的两个项是顺序进行的。 换句话说,调用了fib(555)
并使用555个堆栈帧完成其工作,这很重要,请展开这些帧,以使您回到调用fib(555)
之前的堆栈级别。 然后调用fib(554)
,它使用大约相同数量的帧。
在任何时候,您都不会使用超过555个额外堆栈帧。 因此,在图形上,它没有做:
_ _
\ /
\ (555 levels) /
\__ __/
\ /
\ (another 554 levels) /
\______________________/
它在做什么是:
_ _ _
\ / \ / (555 levels down, then
\ / \_/ back up, then down
\_/ 554, then back up again)
无论如何,使用递归来计算斐波那契数是非常低效的,因为对于999
,您要计算两次 fib(998)
,一个作为第一项fib(999)
(对998
进行一次堆栈下移),另一个作为第一个项。第二学期fib(998)
。 然后,对于这两个fib(998)
调用中的每一个 ,您fib(997)
两次计算fib(997)
。 这是一种非常耗时的方法,运行时会平方上升(该术语可能是错误的,并且那些数学上更多的名词可以纠正我,但我的意思是,它随数字的平方而上升)。
使用迭代解决方案要好得多,例如下面的伪代码(由于Python是理想的伪代码语言,因此,它看起来与Python毫无疑问,非常相似):
# Calculate Fibonacci, first term fib(0).
def fib(n):
if n <= 1: return 1
grandparent = 1
parent = 1
for i in range(n - 1):
me = parent + grandparent
grandparent = parent
parent = me
return me
for i in range(10):
print i, fib(i)
这比递归解决方案有效得多,并且堆栈溢出没有问题。 它几乎立即返回fib(999)
:
70330367711422815821835254877
18354977018126983635873274260
49050871545371181969335797422
49494562611733487750449241765
99108818636326545022364710601
20533741212738673391111981393
73125598767690091902245245323
403501
相对于整整十分钟,我在无聊和徘徊之前一直等待递归解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.