ES6 入门系列 (三) 尾递归

  递归咱们不陌生,函数

  那什么是尾递归呢?优化

  为何要用尾递归呢?spa

  尾递归怎么用呢?code

  带着这三个问题咱们来了解它,blog

咱们知道递归很是耗费内存,一不当心就会发生‘栈溢出’, 相信你必定遇到过这个错误: stack overflow,递归

尾递归就是用来优化递归的这个问题的。内存

  尾递归的定义: 在函数的最后一步返回自身,也就是显示地return自身就称为尾递归。对于尾递归来讲,io

因为只存在一个调用帧,因此永远不会发生‘栈溢出’。console

  咱们来举例说明尾递归的好处:function

  • 好比计算n的阶乘, 咱们首先想到找规律, n的阶乘等于n* (n-1)的阶乘
  • 找出口1的阶乘等于1
  • 而后咱们就很天然的用递归写出
  • function jieCheng(n) {
        if (n===1) {
            return 1
        }
        return n * jieCheng(n -1);
    }
    const result = jieCheng(5);
    
    console.log(result);  // 120

    很天然, so easy有木有,

   but,  这样咱们每递归一次,上一次的调用记录还保存着, 也就是说咱们计算n的阶乘最多要保存n个调用记录,复杂度为O(n).

   改为尾递归:

   

function weiJieCheng(n, total=1) {
    if (n === 1) {
        return total;
    }
    return weiJieCheng(n-1, n * total);
}

console.log(weiJieCheng(5), 'wei'); // 120

  把中间变量改写成函数的参数, 这样就只保存了一个调用记录,复杂度为O(1)。

  再用蹦床函数对尾递归进行优化,把递归执行转换成循环执行:

function trampoline(f) {
    while(f && f instanceof Function) {
         f = f ();
    }      
}
trampoline(weiJieCheng(5, 1))
相关文章
相关标签/搜索