当前位置: 首页 > 面试题库 >

头尾递归的区别

林英锐
2023-03-14
问题内容

我试图得到这两种递归策略之间的区别。

我被告知的定义如下:

尾递归: 如果调用返回后无需执行任何操作,则调用为尾递归,即当调用返回时,立即从调用函数返回返回的值

Head递归: 当函数的第一条语句是递归调用时,调用是head递归的。


问题答案:

在中head recursion,递归调用在发生时先于函数中的其他处理(考虑它发生在函数的顶部或头部)。

在中tail recursion,情况恰恰相反—处理发生在递归调用之前。在这两种递归样式之间进行选择似乎是任意的,但是选择可以使一切有所不同。

具有在路径的开头具有单个递归调用的路径的函数使用所谓的头递归。先前展览的阶乘功能使用头部递归。一旦确定需要递归,它所做的第一件事就是使用递减的参数进行调用。在路径末尾具有单个递归调用的函数正在使用尾递归。
请参阅这篇文章

递归示例:

public void tail(int n)         |     public void head(int n)
{                               |     {
    if(n == 1)                  |         if(n == 0)
        return;                 |             return;
    else                        |         else
        System.out.println(n);  |             head(n-1);
                                |
    tail(n-1);                  |         System.out.println(n);
}                               |     }

如果递归调用发生在方法的末尾,则称为tail recursion。尾递归为similar to a loop。的method executes all the statements before jumping into the next recursive call

如果递归调用发生在beginning of a method, it is called a head recursion。的method saves the state before jumping into the next recursive call



 类似资料:
  • 我对函数式编程很陌生,尤其是下面使用的Scheme。我正在尝试使以下函数是递归的,尾递归的。基本上,该函数的作用是对两个字符串的对齐方式进行评分。当给定两个字符串作为输入时,它会比较每个“列”字符,并根据在称为 scorer 的函数中实现的评分方案(由下面的代码中的函数调用)来累积该对齐的分数。 我有一个想法,用一个帮助函数来累积分数,但我不太确定如何去做,因此我该如何让下面的函数尾递归呢?

  • 尾递归优化 recur 尾递归优化是函数式编程不能缺少的一个性能优化方案. 没有尾递归, 常有的递归调用也会形成很深的调用栈消耗内存. cljs 和 Clojure 类似, 都需要通过声明 recur 进行优化. 最终代码会被编译为 white 结构的 js 代码,从而提高性能. (defn factorial [acc n] (if (<= n 1) acc (recur (* ac

  • 我有一个家庭作业问题,它给出了一个递归函数,我必须使用尾部递归来实现它。函数为f(0)=1 f(n)=1 2*f(n-1) 我并不擅长尾部递归,我试着查找示例,但我发现的都是没有斐波那契序列的示例,这没有多大帮助。 我真正拥有的是 我知道尾递归基本上每次调用都计算函数,我只是不知道如何实现它。 编辑:我打了一个错字f(n)应该是1 2*f(n-1)

  • 我有一个关于如何将“递归”转换为“尾部递归”的问题。 这不是家庭作业,只是在我试图润色算法书籍中的递归定理时出现的一个问题。 我熟悉使用递归的两个典型示例(阶乘和斐波那契序列),也知道如何以递归方式和尾部递归方式实现它们。 我的代码如下(我使用Perl只是为了使其简单,但可以轻松地转换为C/Java/C)。 运行代码时,输出如下: 递归函数在返回之前使用不同的参数调用自己两次。我尝试了几种方法将其

  • 假设我编写这样的代码: 我如何让Kotlin优化这些相互递归的函数,以便在不抛出StackOverflower错误的情况下运行main?tailrec关键字适用于单函数递归,但没有更复杂的功能。我还看到一个警告,在使用关键字tailrec的地方没有找到尾部调用。也许这对编译器来说太难了?

  • 最初,我发布了一个问题“理解尾部递归向量- Q2)尾递归,这让我很难理解。我理解他们为什么需要尾递归,基本上他们用它来避免迭代,所以他们使用helper作为中间例程...所以他们可以避免将每次迭代放入堆栈...类似这样的东西。和letrec/lambda表达式,如下所示: 第Q2-2行:为什么这是“局部递归”“局部”对我来说是递归的中间例程。。。在这里中间意味着我的理解。。 [我的困惑]尾递归是不