练习9:尾递归优化
尾递归和普通递归有啥区别
尾调用,是指函数内部的最后一个动作是函数调用。该调用的返回值,直接返回给函数。
举个例子:
// 尾调用
function f(x){
return g(x);
}
// 非尾调用
function f(x){
return g(x) + 1;
}
模拟下上述执行上下文栈:
尾调用:
ECStack.push(<f> functionContext)
ECStack.pop()
ECStack.push(<g> functionContext)
ECStack.pop()
非尾调用:
ECStack.push(<f> functionContext)
ECStack.push(<g> functionContext)
ECStack.pop()
ECStack.pop()
也就说尾调用函数执行时,虽然也调用了一个函数,但是因为原来的的函数执行完毕,执行上下文会被弹出,执行上下文栈中相当于只多压入了一个执行上下文。然而非尾调用函数,就会创建多个执行上下文压入执行上下文栈。
函数调用自身,称为递归。如果尾调用自身,就称为尾递归。
尾递归优化例子
阶乘优化:
function factirial(n, total = 1) {
if (n < 2) return total
return factirial(n - 1, n * total)
}
factorial(5,1) // 5 * 4 * 3 * 2 * 1 = 120
累加求和:
function sum(n, total = 0) {
if (n < 1) return total
return sum(n-1, n + total)
}
sum(5,1) // 5 + 4 + 3 + 2 + 1 = 15
斐波那契:
function fib(n, sum1 = 1, sum2 = 2) {
if (n < 2) return sum2
return fib(n-1, sum2, sum1 + sum2)
}
fib(100)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了