最近在看一本书:算法图解,然后刚好看到了递归,自以为很简单的嘛,然后就啪啪啪的打脸了。为啥原因被打脸呢?请看下面简单的递归求数组和的函数:
function sum (arr, value){
if(arr.length){
value += arr.pop();
sum(arr,value);
}
return value;
}
sum([1,2,3],0);
复制代码
如果执行以上代码,你会发现:最终结果返回了3。当时很是纳闷?为什么会产生这个结果呢,
带着这个疑问 我就好好又温习了一遍递归章节
首先你必须知道 递归的两大条件:基线条件和递归条件
1、基线条件:指的是停止调用自己的条件
2、递归条件:指的是调用自身的条件
知道了两大条件后我们还需要了解到 递归函数的原理:既计算机是如何调用递归式的函数:
1、计算机中有一个调用栈的内存空间,这个空间 专门用于存放计算机将要调用的函数列表。
2、调用栈的两种使用方式,压入栈和弹出栈,这两个方法,好似存放和再拿出来使用。
3、递归函数,其实刚开始执行时,是先把已知的待执行函数都存放到调用栈中,然后依次执行,由于栈是先进后出的,所以递归函数的执行顺序是和我们想象中的有所不同的。
好了,了解完递归的原理后,我们再拿开篇的函数sum 执行你会发现,刚开始执行时:sum([1,2],3)被放到待执行栈中。然后依次是sum([1],5)、sum([],6) 因为栈的特性:所以执行顺序刚好是相反的,sum([],6) => sum([1],5) => sum([1,2],3) 所以我们最终得到的 3
具体执行顺序请看完整的流程图:
其实正确的写法很简单,并不需要传递多余的参数:
function sum(arr){
if(arr.length){
return arr.pop() + sum(arr)
}
return 0
}
sum([1,2,3]);
复制代码
你get 到递归函数的技能了吗?