Java head与amp;尾部递归

Java head与amp;尾部递归,java,recursion,difference,Java,Recursion,Difference,我试图找出这两种递归策略之间的区别 我被告知的定义如下: 尾部递归:如果在调用返回后无需执行任何操作,即当调用返回时,调用函数立即返回返回值,则调用为尾部递归 头递归:当函数的第一条语句是递归调用时,调用是头递归的。在头递归中,递归调用发生时,位于函数中其他处理之前(想象它发生在函数的顶部或头) 在尾部递归中,与递归调用之前的处理相反。在这两种递归样式之间进行选择似乎是任意的,但是这种选择会产生很大的不同 具有路径且在路径开头有一个递归调用的函数使用所谓的头递归。前面展示的阶乘函数使用头递归。一

我试图找出这两种递归策略之间的区别

我被告知的定义如下:

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


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

头递归中,递归调用发生时,位于函数中其他处理之前(想象它发生在函数的顶部或头)

尾部递归
中,与递归调用之前的处理相反。在这两种递归样式之间进行选择似乎是任意的,但是这种选择会产生很大的不同

具有路径且在路径开头有一个递归调用的函数使用所谓的头递归。前面展示的阶乘函数使用头递归。一旦确定需要递归,它要做的第一件事就是使用递减参数调用自己。 在路径末尾有一个递归调用的函数使用尾部递归。

递归示例:

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);
}                               |     }
如果递归调用发生在方法的末尾,则称为
尾部递归
。尾部递归类似于循环。
方法在跳转到下一个递归调用之前执行所有语句


如果递归调用发生在方法的
开头,则称为头递归。
方法在跳转到下一个递归调用之前保存状态

嗯。。。尾部递归是另一回事。尾部调用优化是一种可应用于尾部递归的优化。它们与你第一段中暗示的不一样。这些基本上不就是OP自己所说的定义吗?你能举一个头部递归的例子吗?因为在我看来,让方法的第一行立即调用递归会产生无限循环,不是吗?像
int recurCall(int number){int res=recurCall(number-1);…进程…;返回res;}
@Sara-我已经给出了理论上和示例上的区别。查看示例后面的段落,它显示了您想要的内容。@javakillღ 好的,谢谢!“头递归”不是我以前听说过的东西。这听起来不是一个有用的概念;递归调用是函数做的第一件事,这是非常罕见的。这排除了确定是否执行调用的任何类型的条件,以及在函数调用之前需要计算的任何参数。在某些语言中,这甚至是不可能的,因为函数必须在运行时计算表达式以确定要递归调用的函数。看起来使用这个术语的来源对“头”有一个非常松散的定义,大致意思是在“真正的工作”之前。我不知道他们为什么定义“头递归”;他们似乎对这一概念毫无兴趣。它肯定没有尾部递归那么有用。区分头部递归和非尾部递归似乎是多余的。@user2357112:请原谅延迟的回答,但是头部递归和尾部递归之间的区别很重要,因为它可能具有内存含义。在递归调用之前计算的任何内容都必须存储在堆栈中,直到计算完整个后续递归函数。某些系统需要更多的内存,因此不能像尾部递归那样深度递归,并且可能会出错。Head递归只是将函数的结果向前传递到下一次迭代的计算中,因此一次只需要存储1个值。@MichaelKupietz:这是向后的。尾部递归可以进行优化,以消除不确定的调用堆栈增长,一些函数式编程语言强制这样做。“头递归”需要维护调用堆栈信息,以防止这种优化。