繁体   English   中英

Fibonacci函数中的递归堆栈溢出

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM