【问题标题】:tail recursive vs iterative algorithms尾递归与迭代算法
【发布时间】:2012-10-05 06:41:45
【问题描述】:

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

我不是在问为什么尾递归比简单递归更好,我认为在任何地方都清楚地解释了。

那为什么

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

优于

sum = 0;
while(n--) sum += n

【问题讨论】:

    标签: recursion tail-recursion iteration


    【解决方案1】:

    递归使程序更具可读性,但性能较差。迭代过程具有良好的性能,但不那么可读,并且可能需要局部变量来存储中间值(可变性)。使用尾递归,您将获得两全其美,并且不需要“总和”变量(不变性)。这在计算大量总和或阶乘时非常有用,因为当您将结果转发到下一个递归函数调用时,您永远不会遇到 stackoverflow 异常。

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

    延伸阅读here

    【讨论】:

    • 在前一种情况下,函数式方法的可读性并不高。我还是应该选择那个版本吗?
    • 你的例子很简单。在这种情况下,迭代是显而易见的选择。要查看迭代、递归、尾递归调用之间的区别,请尝试这个。 ideone.com/i0md7
    • 所以你是说尾递归可能比迭代更有效(斐波那契高出 6 倍)? fibonacciIt - 位置:10000 时间:137275432 ns fibonacciTail- 位置:10000 时间:20357861 ns 我会检查自己:D。谢谢
    【解决方案2】:

    递归消耗更多的内存(堆栈帧的开销)和更多的 CPU 周期(创建和销毁堆栈帧的开销)。然而,它使代码更具可读性。迭代会降低代码的可读性,但会释放更多的内存和 CPU,因此可能需要用于受限环境,例如物联网设备、电话等。有关详细说明,请参见此处https://www.ocf.berkeley.edu/~shidi/cs61a/wiki/Iteration_vs._recursion#:~:text=Iteration%20and%20recursion%20are%20both%20ways%20to%20achieve%20repetition%20in%20programs.&text=All%20iterative%20functions%20can%20be,is%20defined%20as%20tail%20recursion

    【讨论】:

    • 虽然递归消耗更多内存,但尾递归不会并且可以直接转换为迭代而不消耗堆栈帧。有时迭代比尾递归更容易理解,问题是为什么仍然更喜欢尾递归?这只是一种纯粹的方法?
    猜你喜欢
    • 2011-02-08
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 2016-06-14
    • 2016-05-09
    • 2016-06-14
    • 2016-06-06
    相关资源
    最近更新 更多