尾递归与递归

31 篇文章 0 订阅
8 篇文章 0 订阅

什么是递归

递归是什么就不多说了,下面举个例子

function f(n) {
  if (n === 1) {
    return 1
  }
  return n * f(n - 1)
}
f(3) // 6

递归非常耗费内存,因为递归调用栈中需要同时保存成千上百个调用记录,很容易发生"栈溢出"错误。

什么是尾递归

如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。----百度百科

简单说,函数在末尾调用函数,就称为尾递归。

//尾递归
function f(x) {
  return g(x);
}

function f(x) {
  if (x > 0) {
    return m(x)
  }
  return n(x);
}

//以下两种都不是尾递归
function f(x) {
  let y = g(x);
  return y;
}

function f(x) {
  return 1 + g(x);
}

尾递归是函数最后一步调用,在所有递归调用记录形成的调用栈中,不需要保留外层函数的调用记录,因为调用位置、内部变量等信息都不会再用到了,只要直接用递归调用中最后一次函数调用的记录就可以了。

递归函数改写尾递归函数

同样是这个求取阶乘的函数,递归函数与尾递归函数写法如下

//递归
//需要保存n条调用记录,复杂度为O(n)
function f(n) {
  if (n === 1) {
    return 1
  }
  return n * f(n - 1)
}
f(3) // 6

//尾递归
//只需调用最后一次调用记录,复杂度O(1)
function f(n, total) {
  if (n === 1) {
    return total
  }
  return f(n - 1, n * total)
}
f(3, 1) // 6

 参考文章

尾调用优化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值