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

时间:2012-03-03 19:23:51

标签: javascript algorithm dom recursion iteration

我有一个递归算法,用于在tree order

中遍历文档树中的节点

如何进行迭代? 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
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

如果存在子节点并使用while(nodes.length)循环,那么如何连接子节点呢?基本上,继续向堆栈添加新节点,并继续运行循环(每次测试一个节点),直到堆栈为空: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);
        }
    }
}

答案 1 :(得分:1)

This article(从Wikipedia's article on tree traversal链接)在JavaScript中提供了一种算法,用于DOM树的迭代前序遍历。引用:

function preorderTraversal(root) {
  var n = root;
  while(n) {
  // If node have already been visited
    if (n.v) {
      // Remove mark for visited nodes
      n.v = 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) {
        n.v = true;
        n = n.firstChild;
      }
      else if (n.nextSibling)
        n = n.nextSibling;
      else
        n = n.parentNode;
    }
  }
}

请注意“// Do something with node here...”行,您可以在此处调用回调函数。

查看完整文章了解更多信息。