[英]Is this tail recursion?
我试图找到尾递归的例子,我真的没有看到常规和尾部之间的区别。 如果这不是尾递归,有人可以告诉我为什么不是?
public static long fib(long index) {
// assume index >= 0
if (index == 0) // Base case
return 0;
else
if (index == 1) // Base case
return 1;
else
// Reduction and recursive calls
return fib(index - 1) + fib(index - 2);
} // end of method fib(long index)
不,问题中的方法不使用尾递归。 尾递归很容易识别:递归步骤是方法中发生的最后一件事。
在你的代码中, 在两个递归调用结束之后,还有一个操作要做 - 一个加法。 所以该方法是递归的 ,但不是尾递归的 。
为了进行比较,这里是fib()
方法的尾递归实现 - 注意我们需要传递额外的参数来保存递归的状态,更重要的是,请注意在递归调用之后没有剩下的操作要做回报。
public static long fib(int n, long a, long b) {
return n == 0 ? b : fib(n-1, a+b, a);
}
像这样使用它:
fib(10, 1, 0) // calculates the fibonacci of n=10
=> 55
之前的实现将在n = 92时正常工作,对于更大的数字,您将不得不使用BigInteger
而不是long
,并且更好地切换到迭代算法。
@ÓscarLópez回答了这个问题。
人们有兴趣知道调用是否是尾调用的原因是有一个优化允许尾部调用被分支替换,从而避免了创建新堆栈帧的需要。 这允许在有界堆栈上进行无界尾递归。
但是,由于您使用java
标记了Question,您应该知道当前的Java实现不实现尾调用优化。 Java中的深度递归方法调用容易导致StackOverflowError
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.