python-递归函数及尾递归优化

时间:2021-08-27 02:43:38

    递归函数定义简单,逻辑清晰,可以使用很少的代码实现较为复杂的功能。但是我们都知道,对于计算机来说,函数的调用都是通过栈(stack)来实现的。每当进行一次函数调用,栈就会增加一层栈帧,以实现函数跳转;每当函数调用结束返回时,栈就相应地减少一层栈帧。如果我们进行大量的递归调用,就会耗尽栈的有限的资源空间,造成栈溢出。

    栈溢出是一种很危险的情况,导致的后果也很严重。我们要想办法保证,我们在进行函数递归调用时,不会造成这种情况。

尾递归优化可以在函数返回的时候,调用自身本身,并且,在return语句中不包含表达式,这样编译器或者解释器就可以吧尾递归进行优化。最后的结果是,不管递归函数进行多少次调用,都只占用一个栈帧,这样就可以避免栈溢出情况的出现。下面以一个简单的例子说明一下:



def fact(n):
'''计算阶乘'''
    if n == 1:
        return 1
    return n * fact(n - 1)

上面的代码是递归调用的一个经典使用,计算n的阶乘。假如n != 1,开始进入return计算语句,在表达式中递归调用fact()自身,一直到n == 1为止。假如n特别大,将有可能造成栈溢出。下面采用尾递归对上述程序进行优化:

def fact(n):
   return fact_iter(n, 1)

def fact_iter(num, product):
    if num == 1:
        return product
    return fact_iter(num - 1, num * product)
我们可以看到,fact_filter()函数的返回语句仅仅是返回递归函数本身,其参数num-1 和num * product在函数调用前就会被计算。每次产生变化的只是函数的参数,而不会发生无限的普通递归函数的调用,这样就可以解决栈溢出问题。