美文网首页
详解什么是尾递归(javascript版本)

详解什么是尾递归(javascript版本)

作者: sphenginx | 来源:发表于2020-04-30 16:39 被阅读0次

在传统的递归中,典型的模型是首先执行递归调用,然后获取递归调用的返回值并计算结果。以这种方式,在每次递归调用返回之前,您不会得到计算结果。传统地递归过程就是函数调用,涉及返回地址、函数参数、寄存器值等压栈(在x86-64上通常用寄存器保存函数参数),这样做的缺点有二:

  • 效率低,占内存
  • 如果递归链过长,可能会statck overflow

尾递归的原理:

当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。编译器可以做到这点,因为递归调用是当前活跃期内最后一条待执行的语句,于是当这个调用返回时栈帧中并没有其他事情可做,因此也就没有保存栈帧的必要了。通过覆盖当前的栈帧而不是在其之上重新添加一个,这样所使用的栈空间就大大缩减了,这使得实际的运行效率会变得更高

在尾递归中,首先执行计算,然后执行递归调用,将当前递归计算的结果传递给下一个递归。这导致最后一个语句采用的形式return (recursive-function params) 。基本上,任何给定递归步骤的返回值与下一个递归调用的返回值相同。

我们考虑一个最基本的关于N的求和函数,(例如sum(5) = 1 + 2 + 3 + 4 + 5 = 15)。

这是一个使用JavaScript实现的递归函数:

function calcSum(x) {
    if (x===1) {
        return x;
    } else {
        return x + recsum(x-1);
    }
}

如果你调用calcSum(5),JavaScript解释器将会按照下面的次序来计算:

calcSum(5)
5 + calcSum(4)
5 + (4 + calcSum(3))
5 + (4 + (3 + calcSum(2)))
5 + (4 + (3 + (2 + calcSum(1))))
5 + (4 + (3 + (2 + 1)))
15

注意在JavaScript解释器计算calcSum(5)之前,每个递归调用必须全部完成。

这是同一函数的尾递归版本:

function tailSum(num, total = 0) {
    if (num ===0 ) {
        return total ;
    } else {
        return tailSum(num -1,  total +num);
    }
}

下面是当你调用tailSum(5)的时候实际的事件调用顺序:

tailSum(5, 0)
tailSum(4, 5)
tailSum(3, 9)
tailSum(2, 12)
tailSum(1, 14)
tailSum(0, 15)
15

在尾递归的情况下,每次递归调用的时候,total 都会更新。

如此, 每次执行完递归, 占用内存的只有一个方法,可以有效的避免因为太多调用而导致的内存泄露

相关文章

  • 详解什么是尾递归(javascript版本)

    在传统的递归中,典型的模型是首先执行递归调用,然后获取递归调用的返回值并计算结果。以这种方式,在每次递归调用返回之...

  • 你可能不知道的递归

    递归 尾递归 CPS trampoline memoize 缓存 本文使用 JavaScript 进行描述。本文简...

  • 什么是尾递归

    本文摘抄自什么是尾递归 问题一:什么是尾递归? 这两个函数都是在计算n的阶乘,结果一样的,但只有下面的factta...

  • JavaScript计算斐波那契数列

    很多语言都提供可尾递归优化,能将尾递归替换为循环方式调用,可以提高计算速度并避免堆栈溢出。但是javascript...

  • 什么是尾调用?什么是尾递归?尾调用的优化?尾递归优化?

    尾调用优化 尾递归(尾调用优化)

  • 尾递归

    尾递归就是操作的最后一步是调用自身的递归。 这是尾递归: (这个程序没什么意义,仅作为理解辅助之用)。 这不是尾递...

  • Kotlin语言(九):特性

    1、尾递归优化 尾递归:函数在调用自己之后没有再执行其他任何操作就是尾递归 尾递归优化的原理就是将递归转换成迭代,...

  • python学习

    1:尾递归 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊...

  • 尾调用优化

    尾调用优化 尾递归 正常递归 尾递归 改写以上代码,使其只有一个参数: 总结一下,递归本质上是一种循环操作。纯粹的...

  • Python的尾递归优化

    今天在刷算法时,遇到尾递归的概念,之前也看到过,但是没有深究,只知道尾递归效率高。今天学习了一下. 什么是尾递归:...

网友评论

      本文标题:详解什么是尾递归(javascript版本)

      本文链接:https://www.haomeiwen.com/subject/ptctghtx.html