2015-12-08 123 views
0

任何人都可以告訴ma有關終端遞歸調用和非終端遞歸調用之間的區別?終端&&非終端遞歸調用

我寫的時候遞歸調用的函數來完成的最後操作

#include <iostream> 

int factorial(int n) 
{ 
    if (n==0 || n==1) 
     return 1; 
    else 
     return n*factorial(n-1); 
} 
+0

所以你寫了一個代碼......它與問題有什麼關係? – LogicStuff

+0

歡迎2bo堆棧溢出。我建議你閱讀http://stackoverflow.com/help/how-to-ask,以便更好地回答你的問題。喜歡在發佈之前閱讀證明。清楚你需要什麼,你嘗試了什麼,你會得到幫助。 – micstr

回答

4

終端遞歸發生。

當從遞歸調用返回時需要做額外的工作時發生非終端遞歸。

你的例子是非終端的,因爲從遞歸調用返回後仍然有一個乘法操作(n*)。最後一行:

return n*factorial(n-1) 

實際上相當於:

int temp = factorial(n-1); 
return temp * n; 

您可以更改factorial()功能是終端與其他參數:

int factorial_x(int n, int f) 
{ 
    if (n==0 || n==1) 
     return f; 
    else 
     return factorial_x(n - 1, f * n); 
} 
int factorial(int n) 
{ 
    return factorial_x(n, 1); 
} 

遞歸調用:

return factorial_x(n - 1, f * n); 

相當於:

int n2 = n - 1; 
int f2 = f * n; 
return factorial(n2, f2); 

正如您所看到的,現在乘法在遞歸調用之前,而不是在之後。在遞歸調用之後沒有任何東西,只有return,所以這是真正的尾遞歸。

+0

和終端遞歸是一個重要的概念,因爲它可以被優化:https://en.wikipedia.org/wiki/Tail_call –

+0

終端代碼將不會工作,因爲'factorial_x'沒有任何基礎條件,並會繼續遞歸併給予stackoverflow錯誤。 – user1719160

+0

@ user1719160:哎唷!你是對的。現在沒關係。 – rodrigo