递归、尾递归(斐波那契数列)

255 阅读1分钟

递归实现斐波那契数列

function fn(n){
    if(n===1||n===2){
        return 1;
    }
    return fn(n-1)+fn(n-2);
}
console.log(fn(1));//1
console.log(fn(2));//1
console.log(fn(3));//2
console.log(fn(4));//3
console.log(fn(5));//5
console.log(fn(6));//8
fn(6)=fn(5)+fn(4);
fn(6)=fn(4)+fn(3)+fn(3)+fn(2);
fn(6)=fn(3)+fn(2)+fn(2)+fn(1)+fn(2)+fn(1)+fn(2);
fn(6)=fn(2)+fn(1)+fn(2)+fn(2)+fn(1)+fn(2)+fn(1)+fn(2);

要想计算fn(6),就必须计算fn(5),在fn(6)里面调用fn(5),在fn(5)未返回结果之前,fn(6)就没法销毁,一直占用内存,fn(5)又依赖于fn(4),这样层层嵌套,形成一个庞大的栈,数值越大,栈越深,导致堆栈溢出。

解决递归堆栈溢出的方法:

1、非递归实现斐波那契数列

function fn(n){
	if(n===1||n===2){
    	return 1;
    }
    let current=0;
    let next=1;
    while(n>1){
    	[next,current]=[next+current,next];
        n--;
    }
    return next;
}

2、尾递归实现斐波那契数列

使用尾递归实现新函数替换旧函数,解决调用栈太多的问题。
function fn(n,current=0,next=1){
	if(n===1){
    	return next;
    }
    return fn(n-1,next,current+next);
}