C++ 两次调用自身作为回报——是否使用尾部递归?

C++ 两次调用自身作为回报——是否使用尾部递归?,c++,fibonacci,tail-recursion,C++,Fibonacci,Tail Recursion,我理解尾部递归,但是我被指派写一个代码来看看第N个斐波那契数是什么。 首先,这段代码确实有效。这不是最好的方法,但它是一种方法——不过我开始担心它不是尾部递归的。代码如下: static int fib_tail_helper(int n, int result) { if (n == 0) { return result; } else if (result == 0) { return fib_tail_helper(n - 1, result + 1); } else

我理解尾部递归,但是我被指派写一个代码来看看第N个斐波那契数是什么。 首先,这段代码确实有效。这不是最好的方法,但它是一种方法——不过我开始担心它不是尾部递归的。代码如下:

static int fib_tail_helper(int n, int result) {
if (n == 0) {
    return result;
}   
else if (result == 0) {
    return fib_tail_helper(n - 1, result + 1);
}
else {
    return fib_tail_helper(n - 1, result + fib_tail_helper(n - 1, 0));
}
}

int fib_tail(int n) {
/*
// REQUIRES: n >= 0
// EFFECTS: computes the Nth Fibonacci number
//          fib(0) = 0
//          fib(1) = 1
//          fib(n) = fib(n-1) + fib(n-2) for (n>1).
// MUST be tail recursive
*/
return fib_tail_helper(n, 0);
}
我最担心的是“返回fib\u tail\u helper(n-1,result+fib\u tail\u helper(n-1),0”。 我觉得这将使用另一个堆栈,因此是非尾部递归的…有人能提供一些输入吗


谢谢!!

不,这不是尾部递归


编译器需要首先计算
fib\u tail\u helper
参数,这意味着在继续调用最后一个
fib\u tail\u helper
作为返回值之前,它将创建n-1个调用堆栈。

要显示它不是尾部递归,转换可能会有所帮助:

static int fib_tail_helper(int n, int result) {
    if (n == 0) {
        return result;
    }   
    else if (result == 0) {
        return fib_tail_helper(n - 1, result + 1);
    }
    else {
        int tailrecursivePreventingValue = fib_tail_helper(n - 1, 0);
        return fib_tail_helper(n - 1, result + tailrecursivePreventingValue);
    }
}

它与您的代码完全相同,但引入了一个解释性变量。您可以看到,在最后一个else块中有两个对fib_tail_helper()的调用。这意味着指数运行时间,因为第二个值取决于第一个值。

tail递归是递归的巧妙实现,它不使用堆栈空间

它的工作原理如下:
如果函数在最后一个动作中调用自身,则称为“尾部递归”。
在这种特殊情况下,编译器可以放弃执行实际的函数调用。它可以执行返回函数开头的
goto
。函数的代码将再次运行,就像它被调用一样。当函数终止时,它将返回堆栈上的最后一个地址,即最初调用递归函数

这种方法保证堆栈不会溢出,不管递归有多深。这就是尾部递归的优点

<坏消息是C++没有自动支持尾递归。< /P> 好消息是,实现尾部递归非常容易。
只需将最后的函数调用替换为返回函数开头的
goto


(如果编译器支持尾部递归,这只是您编写的
goto

如果您想确保检查编译器输出。