美文网首页
递归和调用栈

递归和调用栈

作者: YQY_苑 | 来源:发表于2019-08-18 13:04 被阅读0次

    递归

    一个简单的递归阶乘

    image.png
     j = (n) =>
          n === 1 ? 1
                  : n * j(n-1)
    
    image.png

    斐波拉契数列

    fib = (n) =>
        n === 0 ? 0 :
        n === 1 ? 1 :
        fib(n-1) + fib(n-2)
    
    image.png

    压栈/计算次数过高

    image.png

    如何降低压栈/计算次数

    压栈:需要调用栈里记录“回到哪”

    尾递归优化

    用迭代替代递归

    f = (n) => f_inner(2, n, 1, 0)
    
    f_inner = (start, end, prev1, prev2) =>
        start === end ? prev1 + prev2 
        : f_inner(start +1 , end, prev1 + prev2, prev1)
    
    image.png

    尾递归的优势,可以不用“回头”,无需压栈

    所有的递归都可以写成循环

    f = (n) => {
      let array = [0, 1]
      for(let i = 0 ; i <= n - 2 ; i++){
        array[i+2] = array[i+1] + array[i]
      }
      return array[array.length -1]
    }
    

    记忆化函数

    记录之前的结果,而不是记录调用的状态

    image.png

    React 优化

    React 优化

    image.png image.png
    • m没有变化
    • onClick就不需要重新执行
    • Child2就无须重新挂载,故Child也无需重新执行
    const memo = (fn) => {
      const memoed = function(key) {
        if (!(key in memoed.cache)) {
          memoed.cache[key] = fn.apply(this, arguments)
            // 注意 memo 只会以第一个参数作为记忆点,但是还是会用 arguments 来调用 fn
        }
        return memoed.cache[key]
      }
      memoed.cache = {}
      return memoed
    }
    
    const x2 = memo((x) => {
        console.log('执行了一次')
        return x * 2
      })
      // 第一次调用 x2(1)
    console.log(x2(1)) // 打印出执行了,并且返回2
      // 第二次调用 x2(1)
    console.log(x2(1)) // 不打印执行,并且返回上次的结果2
      // 第三次调用 x2(1)
    console.log(x2(1)) // 不打印执行,并且返回上次的结果2
    
    
    // 执行结果
    
    > "执行了一次"
    > 2
    > 2
    > 2
    

    相关文章

      网友评论

          本文标题:递归和调用栈

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