斐波那契数列尾递归优化

斐波那契数列(兔子数列)

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)
递归算法:

function f(n){
    if (n<=2){
        return 1;
    }else{
    //根据斐波那契数列递推的方法定义F(n)=F(n - 1)+F(n - 2)
        return f(n-1)+f(n-2);
    }
}
console.log(f(5));//当输入5时会打印5(打印当前输入第n个数的值)
//console.log(f(100));不要尝试

递归算法存在的问题:
1. 栈的大小是固定的,这也就意味着不能无限的递归。递归到某些时候,栈顶将会没有更多空间来添加新的栈顶,就像水杯容量是固定的,水杯满了就无法再添加了。
2. 递归需要做许多函数调用,每个函数调用都需要设置有一个栈帧,并传递参数,这些都增加了时间开销,即时间复杂度较高。
尾递归:

//num可以理解为  num为n-1   sum为n-2
function Fibonacci(n,num=1,sum=1){
//这里是对数列的打印
    console.log(sum);
    if (n<=2){
        return sum;
    }
    //在结尾调用自己 (n自减一,sum传给num,num+sum传给sum)
    return Fibonacci(n-1,sum,num+sum);
}
console.log(Fibonacci(8));
//console.log(Fibonacci(100));可以尝试

尾递归方法对递归算法进行的优化,因为编译器知道一旦执行了尾递归调用,就不需要先前的变量副本,因为没有更多的代码可以执行,降低了时间复杂度。
上述代码中还存在着一个问题:
输入的n值过大打印出来的数会失去精度。
解决办法:
ES2020 引入了一种新的数据类型 BigInt(大整数),来解决这个问题。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。
如下代码:

function Fibonacci(n,num=1n,sum=1n){
    // console.log(sum);
    if (n<=2){
        return sum;
    }
    return Fibonacci(n-1n,sum,num+sum);
}
console.log(Fibonacci(1000n));
//会输出43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875n(精确表示)
//没有用BigInt(大整数)则会输出4.346655768693743e+208(失去精度)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值