pycharm 递归 栈溢出_递归的优化

3cfa3a13a260a640b35ab7361e93aad4.png

什么是递归?

所谓的递归就是在函数体内调用本函数。使用递归函数一定要有结束的条件,否则就会进入死循环。关于递归有两个经典的案列,比如阶乘、斐波那契数列

下面以斐波那契数列数列为例:

斐波那契数列数列:1 1 2 3 5 8 13 21 34.……

fib(1) = 1 fib(2) = 1 fib(n) = fib(n-1) + fib(n-2)

递归实现

function fib(n) {
if(n === 1 || n ===2) return 1
return fib(n) = fib(n-1) + fib(n-2)
}

递归的缺点

在递归执行的时候,会调用一个又一个的函数,每次调用函数的时候都会压入调用栈,直到得到一个返回值,才会一级一级的出栈,比如:同事A让同事B帮忙解决一个问题,B又找同事C帮忙,如果C能够解决问题告诉B,B得到答案(出栈),B再告诉A,A得到答案(出栈),未解决问题之前,A和B都压入了调用栈,如果调用的函数太多,而栈的内存有限,就会出现栈溢出

递归的另一个缺点就是重复计算,以上面斐波那契的代码为例,如果传入参数5,那么计算过程是这样的:

53cd8a1c2f897f103365af5539645e9b.png

上面就可以看出,fib(3)计算了两次,如果递归计算大数字,就会出现很多函数重复计算,导致性能非常差

递归的优化

不用递归实现

function fn(n) {
  let last1 = 1, last2 = 1, temp
  for(let i = 3; i <= n; i++) {
    temp = last1 + last2
    last1 = last2
    last2 = temp
  }
  return last2
}

空间换效率

function fib(n) {
  let arr = [0, 1, 1]
  let(i=3; i<=n; i++) {
    arr[i] = arr[i-1] + arr[i-2]
  }
  return arr[n]
}

定义一个缓存数组,存储已经计算过的数列,每次计算前看看数组里有没有,如果有直接用,如果没有就计算,然后存在数组,以便下一次计算使用

function fib(n) {
  let cache = [0, 1, 1]
  function _fib(n) {
    if(cache[n]) return cache[n]
    cache[n] = _fib(n-1) + _fib(n-2)
    return cache[n]
  }
  return _fib(n)
}

本文参考自饥人谷前端课程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值