zoukankan      html  css  js  c++  java
  • ES6 入门系列 (三) 尾递归

      递归我们不陌生,

      那什么是尾递归呢?

      为什么要用尾递归呢?

      尾递归怎么用呢?

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

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

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

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

    由于只存在一个调用帧,所以永远不会发生‘栈溢出’。

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

    • 比如计算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))
  • 相关阅读:
    面试题:redis事务
    哲学家就餐问题
    面试题:Redis常见性能问题和解决方案?
    取势、明道、优术、践行、合众
    自主可控和开源
    关于独立思考
    警惕软件复杂度困局
    如何构建研发体系
    大数据整体链路
    银行数仓的建设实践
  • 原文地址:https://www.cnblogs.com/LHLVS/p/10947551.html
Copyright © 2011-2022 走看看