为什么在执行代码(1)时导致最大递归限制错误,而在执行代码(2)时没有错误

时间:2018-10-30 20:36:49

标签: python recursion fibonacci

因此,这是使用递归函数的Fibonacci系列的2个python代码。我想知道这些代码之间的区别,以及为什么code(1)不能正常工作,而code(2)可以正常工作而没有错误?

这不起作用,并显示最大递归限制错误:

def f(n):
   return f(n-1) + f(n-2)

n=8
f(n)

这可行:

def f(n):
   if n == 0:
      return 0
   if n == 1:
      return 1
   else:
      return f(n-1) + f(n-2)

f(4)

1 个答案:

答案 0 :(得分:2)

您的第一个代码无法停止。它没有n == 0或n == 1的基本情况,因此它将无限地向下延伸并带有负数。

如果添加:

  if n <= 1:
      return 0

你真金。 (尽管这是斐波那契的非常低效的实现)。

为什么效率低下,好吧,因为每个子树都经过多次计算。 f(8)调用f(7)和f(6),但是f(7)也调用f(6),因此您得到了指数递归树。您的运行时间将为O(2 ^ n)。这确实很糟糕,通常即使低至50,也无法计算n的fib。

如果包含备忘录,则可以做得更好:

from functools import lru_cache

@lru_cache(maxsize=None)
def fib2(n):
    if n <= 1:
        return n
    else:
        return fib2(n-1) + fib2(n-2)

这将记住您是否曾经打电话给f(n)并返回您上次执行的答案。现在的问题是,您需要记住以前的被叫号码,因此当您的运行时间减少到O(n)时,您的空间需求现在也变为O(n)。

您可以再次放弃所有递归函数,从而进一步改进

def fib3(n):
if n == 0:
    return 0
f1 = 0
f2 = 1

for i in range(n-1):
    f1,f2 = f2, f1+f2
return f2

这更好,因为您随时都只记住两个数字。