尾递归解决递归时的栈溢出错误

递归是非常耗内存的,因为需要同时保存成千个调用帧,容易发生栈溢出错误,但如果使用尾递归的话,由于只存在一个调用帧,所以不会发生栈溢出错误.

  • 例1: 阶乘计算
function  factorial  (n)  {
	if  (n  ===  1)  return  1;
	return  n  *  factorial(n  - 1) ;
}
factorial(5)  //  120
factorial(100)  //  Stack Overflow error

上述代码是一个阶乘函数,尾部有赋值,不属于函数尾调用,计算n次阶乘会有n个调用帧,解决方法如下:

function  factorial  (n ,  total)  {
	if  (n  ===  1)  return  total ;
	return  factorial(n  - 1, n  *total );
}
	factorial(5,  1)  //  120

但是这样写有个不直观的缺点,优化如下
优化1:

function  tailFactorial  (n ,  total)  {
	if  (n  ===  1)  return  total ;
	return  tailFactorial(n  - 1 ,  n  *total);
}
function  factorial(n)  {
	return  tailFactorial(n ,  1);
}
factorial(5)  //  120

优化2:柯里化

function  currying(fn,  n)  {
	return  function  (m)  {
		return  fn.call(this , m,  n) ;
	}
}
function  tailFactorial  (n ,  total)  {
	if  (n  ===  1)  return  total ;
	return  tailFactorial(n  - 1,  n *  total);
}
const  factorial  =  currying(tailFactorial,  1) ;
factorial(5)  //  120

优化3: es6函数默认值

function  factorial  (n,  total  =  1) {
	if  (n  ===  1)  return  total;
	return  factorial(n  - 1 ,  n  *total) ;
}
factorial(5)  //  120
  • 例2: 计算斐波那契数列第n个数值
function Fibonacci(n) {
	if ( n <= 1 ) {return  1};
	return Fibonacci(n - 1) + Fibonacci(n - 2);
}
Fibonacci(10) //89
Fibonacci(100) //栈溢出错误

解决:

function  Fibonacci2 (n , acl = 1, ac2 = 1) {
if ( n <= 1) {return  ac2} ;
return  Fibonacci2 (n  - 1, ac2, acl + ac2);
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值