简体   繁体   English

如何避免两次走树

[英]How to avoid walking the tree twice

I have the following method to initialize a tree:我有以下方法来初始化一棵树:

function _initTree(treeObj, options){ 
    treeObj = treeObj || []; 
    if(!zpJSUtils.isArray(treeObj)) throw new Error("Input tree must be an array"); 
    this.tree = treeObj; 
    this.rootNode = treeObj[0]; 
    _buildNodes.call(this, treeObj); 
} 

The init method walks the tree to initialize all objects as nodes: init方法遍历树以将所有对象初始化为节点:

function _buildNodes(treeObj){ 
    traverseTree.call(treeObj, function(nodeObj){
        node = new Node(nodeObj); 
        return true; 
    }, this); 
} 

The traverseTree method (selected from a switch): traverseTree 方法(从一个开关中选择):

function _walkPreOrder(tree, callback, ctx){ 
    tree.forEach(function(node, idx){ 
        var continueWalk = callback.call(ctx, node); 
        if(continueWalk){
            if(node.hasChildren()){ 
                _walkPreOrder.call(this, node); 
            }; 
        }; 
    }, this); 
}

The question is this.问题是这个。
I want to calculate the height of the tree on init, which is the number of edges on the longest downward path between the root node and a leaf.我想在 init 上计算树的高度,它是根节点和叶子之间最长向下路径上的边数。
So it seems that in order to calculate the height, I'll have to walk the tree again (to find the level of the deepest nested element).所以似乎为了计算高度,我必须再次遍历树(以找到最深嵌套元素的级别)。

The format of the json is this: json的格式是这样的:

var json = [{ text: "root", children: [
    {id: "id_1", text: "node_1", children:[
        {id: "id_c1", text: "node_c1"}, 
        {id: "id_c2", text: "node_c2", children: [
            {id: "id_c2_c1", text: "node_c2_c1"}, 
            {id: "id_c2_c2", text: "node_c2_c2"}, 
            {id: "id_c2_c3", text: "node_c2_c3"}]},   
        {id: "id_c3", text: "node_c3"}]}, 
    {id: "id_2", text: "node_2"}]}]; 

The problem is that the _walkPreOrder could accept multiple callbacks (eg array), but that would result in an dubious api (since passing in multiple functions makes the possibility to continue walking the tree when the condition is true/false dubious).问题是_walkPreOrder可以接受多个回调(例如数组),但这会导致可疑的 api(因为传入多个函数使得当条件为真/假时有可能继续遍历树)。

What would be a good way to solve this problem, ie to avoid multiple iterations?什么是解决这个问题的好方法,即避免多次迭代?

  1. On the first time you walk the tree while creating the child nodes, either return or mark each child with its max-height.第一次在创建子节点时遍历树,返回或标记每个子节点的最大高度。
  2. Then upon visiting all children, compare the maximum of all the child heights, and then mark/return the current node with 1 more than the max height of its children.然后在访问所有子节点时,比较所有子节点高度的最大值,然后将当前节点标记/返回比其子节点的最大高度多 1。

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

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