Recursion 尾部递归与迭代算法

Recursion 尾部递归与迭代算法,recursion,tail-recursion,iteration,Recursion,Tail Recursion,Iteration,我找不到描述为什么尾部递归函数应该优先于迭代算法的文章 我并不是在问为什么尾部递归比简单递归好,我认为简单递归在任何地方都有明确的解释 那为什么呢 sum(n) = { def sumImpl(n, acc) = if(n <= 0) acc else sumImpl(n - 1 , n + accumulator) sumImpl(n, 0) } 递归使程序可读性更强,但性能较差。迭代过程具有良好的性能,但可读性不强,可能需要一个局部变量来存储中间值(可变性)。使用尾

我找不到描述为什么尾部递归函数应该优先于迭代算法的文章

我并不是在问为什么尾部递归比简单递归好,我认为简单递归在任何地方都有明确的解释

那为什么呢

sum(n) = {
    def sumImpl(n, acc) = if(n <= 0) acc  else sumImpl(n - 1 , n + accumulator)
    sumImpl(n, 0)
}

递归使程序可读性更强,但性能较差。迭代过程具有良好的性能,但可读性不强,可能需要一个局部变量来存储中间值(可变性)。使用尾部递归,您将充分利用这两个方面,不需要“sum”变量(不变性)。这在计算大数和或阶乘时非常有用,因为在将结果转发到下一个递归函数调用时,永远不会出现stackoverflow异常

在并行环境中,不变性非常重要。尝试编辑代码并将非常大的数字传递给函数以查看差异


进一步读取

递归会消耗更多内存(堆栈帧的开销)和更多cpu周期(创建和销毁堆栈帧的开销)。然而,它使代码更具可读性。迭代会降低代码的可读性,但会释放更多的内存和cpu,因此,受限制的环境(如物联网设备、电话等)可能需要迭代。有关详细说明,请参见此处。

在前一种情况下,功能性迭代的可读性不高。我还应该选择那个版本吗?你的例子很简单。在这种情况下,迭代是明显的选择。要查看迭代调用、递归调用和尾部递归调用之间的区别,请尝试以下方法。那么你是说尾部递归的可能比迭代的效率更高(斐波那契的效率高6倍)?fibonacciIt-位置:10000次:137275432纳秒fibonacciTail-位置:10000次:20357861纳秒我会检查自己:D。谢谢当递归消耗更多内存时,尾部递归不会,并且可以直接转换为迭代,而无需消耗堆栈帧。有时迭代比尾部递归更容易理解,问题是为什么仍然喜欢尾部递归?这只是一种纯粹的方法?
sum = 0;
while(n--) sum += n