尾递归是递归的一种,特点是函数执行的最后一步是返回函数自身调用,如:
function fn(a, b) {
if(b === 1) return 1;
return fn(a-1, b-1);
}
这意味着在将下一个函数B加入递归调用栈前,可以将前一个函数A弹出销毁,因为B无需A的执行上下文环境。
拿求前N项和来说,N=3
非尾递归写法
function recursion(n) {
if(n === 1) return n;
return recursion(n-1) + n;
}
/*
递归栈调用情况:
push: recursion(3)
push: recursion(2)
push: recursion(1) = 1
pop: 1 + 2 = 3
pop: 3 + 3 = 6
pop: 6
*/
尾递归写法
function recursion(n, sum = 0) {
if(n === 0) return sum;
return recursion(n-1, sum + n);
}
/*
递归栈调用情况:
push: recursion(3, 0)
pop:
push: recursion(2, 3)
pop:
push: recursion(1, 5)
pop:
push: recursion(0, 6)
pop: 6
*/
尾递归没有向上回溯这一环节,由线性空间复杂度降到常数空间复杂度。
将非尾递归转换为递归写法,只需要将需要的中间变量传作参数即可。