资讯专栏INFORMATION COLUMN

《javascript语言精粹》学习笔记 - 递归函数

Ryan_Li / 3276人阅读

摘要:递归函数就是会直接或者间接地调用自身的一种函数。一般来说,一个递归函数调用自身去解决它的子问题。书上第二个例子是说递归函数可以非常高效率的操作树形结构,比如。有一些语言提供了尾递归的优化。好运的是,给我们带来了尾递归,详细迎接使用尾递归。

  

递归函数就是会直接或者间接地调用自身的一种函数。递归是一种强大的编程技术,它把一问题分解为一组相似的子问题,每一个都用一个寻常解去解决。一般来说,一个递归函数调用自身去解决它的子问题。

书上的一个小例子“汉诺塔”。塔上有3根柱子和一个套直径都不同的空心圆盘。开始时源柱子的所有圆盘都按照从小到大的顺序堆叠。目标是每次移动一个圆盘到另一根柱子,最终把一堆圆盘移动到目标柱子上,期间不允许把较大的圆盘放在较小的圆盘上。

 var hanoi = function(disc, src, aux, dst){
    if (disc > 0) {
        hanoi(disc - 1, src, dst, aux);
        document.writeln("Move disc" + disc + " form " + src + " to " + dst);
        hanoi(disc - 1, aux, src, dst);
    }
};

hanoi(3, "src", "aux", "dst");

运行代码结果:

Move disc1 form src to dst
Move disc2 form src to aux
Move disc1 form dst to aux
Move disc3 form src to dst
Move disc1 form aux to src
Move disc2 form aux to dst
Move disc1 form src to dst

hanoi函数把一堆圆盘从一根柱子移动到另外一根柱子,必要使用辅助的柱子。它把该问题拆分成3个小问题。它先移动到一对圆盘中较小的圆盘到辅助柱子上,从而露出下面较大的圆盘,然后移动下面的圆盘到目标柱子上。最后,他将刚才较小的圆盘从辅助柱子上再移动到目标柱子上。通过递推地调用自身去处理一堆圆盘的移动,从而解决那些问题。

传递给hanoi函数的参数包括当前移动的圆盘的编号和它将要用到的3根柱子。当它调用自身的时候,它去处理当前正在处理的圆盘之上的圆盘。最终,他会一个不存在的圆盘编号去调用。在这样的情况下,他不执行任何操作。由于该函数对非法只不理会,也不用担心死循环的问题。

书上第二个例子是说递归函数可以非常高效率的操作树形结构,比如DOM。每次递归调用是处理指定的树的一小段。

// 它从某个指定的节点开始,按照 HTML 源码中的顺序访问该数的每个节点。
var walk_the_DOM = function(node, func){
    func(node);
    node = node.firstChild;
    while (node) {
        walk_the_DOM(node, func);
        node = node.nextSibling;
    }
};

// 它调用 walk_the_DOM 函数,传递一个用来查找节点属性名的函数为参数。
// 匹配的节点会累加到一个结果数组里面。
var getElementsByAttribute = function(att, val){
    var results = [];

    walk_the_DOM(document.body, function(node){
        var actual = node.nodeType === 1 && node.getAttribute(att);
        if (typeof actual === "string" && (actual === val || typeof value 
            != "string")) {
            results.push(node);
        }
    });

    return results;
};

有一些语言提供了尾递归的优化。这意味着如果一个函数返回自身递归的结果,那么调用的过程会被替换成以循环,可以提高速度。可惜js并没有尾递归的优化。

  

好运的是,ES6给我们带来了尾递归,详细迎接ECMAScript 6, 使用尾递归。
拓展:什么情况下用递归?。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85587.html

相关文章

  • JavaScript 语言精粹》 读书笔记 - 函数(二)

    摘要:对象被传递到从句中被捕获。一些语言提供了尾递归优化。这意味着如果一个函数返回自身递归调用的结果,那么调用的过程会被替换为一个循环,可以显著提高速度。构建一个带尾递归的函数。语言精粹读书笔记函数 第四章 函数 Functions (二) 参数 arguments arguments数组: 函数可以通过此参数访问所有它被调用时传递给它的参数列表,包括哪些没有被分配给函数声明时定义的形式参数...

    lufficc 评论0 收藏0
  • 【阅读笔记JavaScript语言精粹

    摘要:对之前看高级程序设计时没有注意到的一些知识点,结合本书做以补充语法注释源于的型既可以出现在字符串字面量中,也可能出现在正则表达式字面量中,如故一般建议使用型注释保留字语句变量参数属性名运算符和标记等标识符不允许使用保留字,此外在对象字面量中 对之前看《JavaScript高级程序设计》时没有注意到的一些知识点,结合本书做以补充 语法 注释 源于PL/I的/* */型既可以出现在字符串字...

    cucumber 评论0 收藏0
  • JavaScript 语言精粹》读书笔记 - 函数

    摘要:语言精粹读书笔记第四章函数函数字面量函数字面量包含个部分第一部分,保留字第二部分,函数名,它可以被忽略。这个超级延迟绑定使得函数对高度复用。构造器调用模式一个函数,如果创建的目的就是希望结合的前缀来调用,那它就被称为构造器构造。 《JavaScript 语言精粹》 读书笔记 第四章 函数 Functions 函数字面量 函数字面量包含4个部分: 第一部分, 保留字 function...

    wdzgege 评论0 收藏0
  • JavaScript语言精粹 修订版》 读书笔记

    摘要:于是我就先把这本薄的经典书语言精粹修订版豆瓣读书本书简介总共章,除去附录,才页,读完并记录了一些笔记。读书笔记还可以分享给别人看。编程语言第版定义了的标准。程序检查时丢弃值为函数的属性。 之前看到这篇文章,前端网老姚浅谈:怎么学JavaScript?,说到怎么学习JavaScript,那就是看书、分析源码。10本书读2遍的好处,应该大于一本书读20遍。看书主动学习,看视频是被动学习。看...

    EscapedDog 评论0 收藏0
  • javascript语言精粹学习笔记 - 继承

    摘要:但采用构造器调用模式,即是使用了前缀去调用一个函数时,函数执行的方式会改变。对象包含构造器需要构造一个新的实例的所有信息。构造器的变量和内部函数变成了该实例的私有成员。 JavaScript 是一门弱类型语言,从不需要类型转换。对象继承关系变得无关紧要。对于一个对象来说重要的时它能够做什么,而不是它从哪里来。 阅读《javascript语言精粹》笔记! 伪类 js的原型存...

    harriszh 评论0 收藏0

发表评论

0条评论

Ryan_Li

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<