📜  尾递归(1)

📅  最后修改于: 2023-12-03 15:09:40.369000             🧑  作者: Mango

尾递归

简介

尾递归是指函数调用自身,并且是在函数的最后执行的递归。相比于普通递归,尾递归优化过的函数可以在编译时进行优化,使得它可以在栈上直接替换为单个调用,而不是递归调用自身。

优化

尾递归和普通递归的区别在于在递归返回的时候是否有需要等待递归函数的返回值。在普通递归中,所有递归返回后,需要在堆栈中暂存每个调用。而在尾递归中,因为返回的数值直接作为参数传给调用者,并且没有其它代码,所以尾递归函数在返回时不需要暂存任何状态,这样可以让编译器进行优化,将尾递归转化为循环语句。

下面是一个经典的 Fibonacci 数列的递归函数:

def fib(n):
    if n < 2:
        return n
    else:
        return fib(n-1) + fib(n-2)

以上代码的时间复杂度为 $O(2^n)$,有明显的指数级别增长的趋势。而加上尾递归优化的代码则如下:

def fib_tail(n, a=0, b=1):
    if n == 0:
        return a
    else:
        return fib_tail(n-1, b, a+b)

以上代码的时间复杂度为 $O(n)$,这是由于每次递归都只是在参数中保存了上一个返回值的状态。这样每次递归调用的状态都可以在进入函数时清空,而不用等其返回值后再进行回溯。

代码片段

C++ 的尾递归优化:

int fib_tail(int n, int a=0, int b=1) {
    if (n == 0) {
        return a;
    }
    return fib_tail(n-1, b, a+b);
}

Python 的尾递归优化:

def fib_tail(n, a=0, b=1):
    if n == 0:
        return a
    else:
        return fib_tail(n-1, b, a+b)
总结

尾递归的优化会比较明显,对于一些可以使用递归解决的问题,使用尾递归优化可以大大提高程序运行效率,降低空间复杂度。但是在实际编写过程中需要注意,过多的使用递归会让程序变得难以维护,还要注意递归的退出条件和递归深度的问题。