Iteration:来回走的过程Recursion:信息的传递需要来回走functionfactorialIterative(number){if(number<0)returnundefined;让总计=1;for(letn=number;n>1;n--){total=total*n;}返回总计;}console.log(factorialIterative(7));//5040递归通常有两个基本要素,一个是基本条件,另一个是递归本身。functionfactorialRecursive(n){//基本条件if(n===1||n===0){return1;}//递归调用returnn*factorialRecursive(n-1);}console.log(factorialRecursive(7));//5040上面的代码执行如下。我们可以看到前7个步骤都是交付流程。满足基本条件后,就开始返程了。让fibNMinus2=0;让fibNMinus1=1;让fibN=n;//n>=2for(leti=2;i<=n;i++){//f(n-1)+f(n-2)fibN=fibNMinus1+fibNMinus2;fibNMinus2=fibNMinus1;fibNMinus1=fibN;}返回fibN;}console.log(fibIterative(10));//55分而治之。分而治之就是分而治之。递归:functionfibRecursive(n){//基本条件if(n<1)return0;//基本条件if(n<=2)return1;//递归+分而治之returnfibRecursive(n-1)+fibRecursive(n-2);}console.log(fibRecursive(10));//55递归中的记忆函数记忆函数常与递归结合使用,来解决这里解决的重复计算问题,在算法中也称为重叠子问题,记忆函数是一个备忘录。函数fibMemo(n,memo=[0,1,1]){if(memo[n]){returnmemo[n];}//递归+分而治之+闭包memo[n]=fibMemo(n-1,memo)+fibMemo(n-2,memo);返回备忘录[n];}console.log(fibMemo(10));//55递归中的尾递归尾递归是指在函数传递结束时执行递归。通过使用尾递归,您最多可以递归n次,因为每次递归都会添加n-1。函数fibTailRecursive(n,lastlast,last){if(n==0){returnlastlast;}if(n==1){最后返回;}返回fibTailRecursive(n-1,last,lastlast+last);}console.log(fibTailRecursive(10,0,1));//55递归中的内存管理我们在使用递归的时候,如果没有很好的控制,就会遇到这个性能问题。那么接下来,让我们看看递归中的内存管理。JavaScript从标准的ES6版本开始就定义了尾调用优化。提到如果一个函数是函数中的最后一个动作,那么它会被当作一个跳转而不是一个子程序。也就是说,这段代码会不断重复,所以有一个基本条件很重要。在实际运行中,大多数浏览器都会定义一个限制来防止堆栈溢出。例如下面的无限循环例子中Chrome调用13952次后,出现超出最大堆栈范围的错误信息,并停止递归。递归复杂度计算的主要定理n是问题的规模,a是子问题的个数,n/b是每个子问题的规模,O(n^{c})是分解原问题并结合子问题时间的解决方案。基于c和log_{b}(a)的比较,有3个结果。log_{b}(a)表示aT(n/b),是解决当前层问题所需的时间复杂度;c代表O(n^{c}),也就是分解原问题,求解子问题的时间来合并。如果公式的形式不符合主定理,可以尝试使用递归公式和递归树。极客时间《Jvascript进阶实战课》学习笔记Day12
