[英]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.