时间:2021-05-26
本文实例讲述了JS尾递归的实现方法及代码优化技巧。分享给大家供大家参考,具体如下:
在学习数据结构和算法的时候,我们都知道所有的递归都是可以优化成栈+循环的。
对于特定的递归函数,一般我们都是手动对它们进行优化的。
在学习scala的时候,接触到尾递归的概念。我们只要将递归写成尾递归方式,编译器会自动帮助我们优化。
ps:并不是所有的递归都可以改写成尾递归
在js中,尾递归通常会被解释器优化。然而,并不是所有的js解释器都支持尾递归优化。
对于不支持尾递归优化的环境,我们需要手动将递归优化成栈+循环。
这里实现了一个通用的方法,将尾递归优化成栈+循环。
代码摘自阮一峰的《ECMAScript入门》这本书。
具体代码如下
function tco(f) { var value; var active = false; var accumulated = []; return function accumulator() { accumulated.push(arguments); if(!active) { active = true; while(accumulated.length) { value = f.apply(this, accumulated.shift()); } active = false; return value; } };}var sum = tco(function(x, y) { if(y > 0) { return sum(x + 1, y - 1); } else { return x; }});let res = sum(1, 5)console.info(res);这段代码非常精妙!
分析
已知,任何递归可以写成循环+栈。
实现将任何尾递归转换成循环+栈执行而不需要针对每个尾递归函数写一个实现版本的思路。
困难在于,任何尾递归,通用实现。而不是针对某一个递归函数。
要点:
栈中保存的数据,正是递归函数的参数。
通用实现,那就必须依赖原来的递归函数,循环的终止条件,正是递归的结束条件。
要将递归函数的参数入栈,而不修改原来的递归函数,就必须用一个函数代替递归函数被调用,从而取得函数入参。
递归函数的终止条件,每一个递归函数都不一样,但是如果递归函数没有被再次调用,说明已达到终止条件。即终止条件和递归函数的调用有关联。而递归函数每次调用,都会将参数入栈。所以可以根据栈中是否有元素,推断是否达到终止条件。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数据结构与算法技巧总结》、《JavaScript数学运算用法总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》
希望本文所述对大家JavaScript程序设计有所帮助。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
这几天看到几篇关于尾递归的文章,之前对尾递归没有多大概念,所以回头研究了一下尾递归。尾递归的概念尾递归(TailRecursion)的概念是递归概念的一个子集。
本文实例讲述了JS基于递归实现网页版计算器的方法。分享给大家供大家参考,具体如下:递归实现网页版计算器可以简化代码,设计思路:1、css+html实现计算器的外
本文实例讲述了js使用正则子表达式匹配首字母与尾字母相同单词的方法。分享给大家供大家参考。具体实现方法如下:复制代码代码如下://子表达式实例:找到首字母与尾字
尾递归简介尾递归是函数返回最后一个操作是递归调用,则该函数是尾递归。递归是线性的比如factorial函数每一次调用都会创建一个新的栈(last-in-firs
本文实例讲述了es6函数之尾递归用法。分享给大家供大家参考,具体如下:函数调用自身,称为递归,如果尾调用自身,就称为尾递归。递归非常耗费内存。因为需要同时保存成