递归
/* 递归 */
function recur(n) {
// 终止条件
if (n === 1) return 1;
// 递:递归调用
const res = recur(n - 1);
// 归:返回结果
return n + res;
}
尾递归
/* 尾递归 */
function tailRecur(n, res) {
// 终止条件
if (n === 0) return res;
// 尾递归调用
return tailRecur(n - 1, res + n);
}
区别
- 递归函数每次调用自身时,系统都需要为新增的函数分配空间,存储局部变量、调用地址等信息,会消耗更多的空间;尾递归因为在最后一步才进行递归调用,会被很多编译器或解释器优化,在空间复杂度上和普通循环函数相当。递归返回上一层级的函数时,还需要进行操作,所以需要保存上下文信息;而尾递归返回上一层函数时无需操作,不需要保留上下文。
- 递归的操作过程是在"归"的步骤;尾递归则是在"递"的过程中。
注:部分编译器不会优化尾递归,比如python默认不支持。