简体   繁体   English

将递归节点遍历转换为迭代节点遍历

[英]Turning recursive node traversal into iterative node traversal

I have a recursive algorithm for traversing nodes in a document tree in tree order 我有一个递归算法,用于按树顺序遍历文档树中的节点

How would this be made iterative? 如何将其迭代? My attempt at making it iterative completely failed 我进行迭代的尝试完全失败

function recursivelyWalk(nodes, cb) {
    for (var i = 0, len = nodes.length; i < len; i++) {
        var node = nodes[i],
            ret = cb(node)

        if (ret) {
            return ret
        }

        if (node.childNodes.length) {
            var ret = recursivelyWalk(node.childNodes, cb)
            if (ret) {
                return ret
            }
        }
    }
}

What about concatenating the child nodes if there are any, and using a while(nodes.length) loop? 如果有子级节点,则串联起来,并使用while(nodes.length)循环怎么样? Basically, keep adding new nodes to the stack, and keep running the loop (testing one node each time) until the stack is empty: http://jsfiddle.net/gEm77/1/ . 基本上,继续向堆栈中添加新节点,并继续运行循环(每次测试一个节点),直到堆栈为空: http : //jsfiddle.net/gEm77/1/

var z = 0; // my precaution for a while(true) loop

function iterativelyWalk(nodes, cb) {
    nodes = [].slice.call(nodes);

    while(++z < 100 && nodes.length) {
        var node = nodes.shift(),
            ret = cb(node);

        if (ret) {
            return ret;
        }

        if (node.childNodes.length) {
            nodes = [].slice.call(node.childNodes).concat(nodes);
        }
    }
}

This article (linked from Wikipedia's article on tree traversal ) gives an algorithm in JavaScript for iterative preorder traversal of a DOM tree. 本文 (从Wikipedia的有关树遍历的文章中链接)提供了JavaScript中用于DOM树的迭代预遍历遍历的算法。 To quote: 报价:

 function preorderTraversal(root) { var n = root; while(n) { // If node have already been visited if (nv) { // Remove mark for visited nodes nv = false; // Once we reach the root element again traversal // is done and we can break if (n == root) break; if (n.nextSibling) n = n.nextSibling; else n = n.parentNode; } // else this is the first visit to the node else { // // Do something with node here... // // If node has childnodes then we mark this node as // visited as we are sure to be back later if (n.firstChild) { nv = true; n = n.firstChild; } else if (n.nextSibling) n = n.nextSibling; else n = n.parentNode; } } } 

Note the line " // Do something with node here... ", which is where you can call your callback function. 请注意“ // Do something with node here... ”这一行,您可以在其中调用回调函数。

Check out the full article for more information. 查看全文,以获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM