以下程序尾是否递归?

时间:2018-12-15 02:36:39

标签: c recursion tail-recursion

我从下面的程序中解释的是它是尾递归的,因为在函数返回时,最后没有什么可求的。我对吗?

void fun(int x) 
{ 
  if(x > 0) 
  { 
     fun(--x); 
     printf("%d\t", x); 
     fun(--x); 
  } 
} 

2 个答案:

答案 0 :(得分:2)

恕我直言,这不是尾巴递归。

关键的区别在于,在尾部递归中,我们先计算值然后进行递归,这意味着我们不需要保留递归堆栈。在非尾递归中,我们先进行递归,然后计算。因此,在最终计算之前,我们必须存储递归堆栈。

在您的情况下,在我们第一次递归结束之前,我们无法执行print步骤,这使得我们必须将x值存储在堆栈中。如果删除了第一个递归调用,则应该是尾递归。

更新

根据https://en.wikipedia.org/wiki/Tail_call,尾部递归应指代调用。如果我们谈论函数调用点的尾递归,那么程序中的第一个调用应该是非尾递归调用,而第二个调用是尾递归调用。

但是对于整个程序,我认为它并不是一个整体tail recursion

答案 1 :(得分:2)

不。对fun()的第一次递归调用必须保存x的当前值,进行新的函数调用,将其传递给副本,然后在调用者的作用域中恢复执行。

这不算在别针头上的天使。尾递归允许进行一些非常重要的编译器优化,例如能够重用相同的堆栈框架并就地更新所有参数值。顶部的非尾部调用无法做到这一点。如果您想证明该功能需要多少堆栈空间的上限,就可以。

也确实是,最后的呼叫(只有该呼叫)是尾递归的。编译器可以对其执行尾递归优化。删除第一个调用,该函数显然是尾递归的。

相关问题