0

私は、子ノードと親ノードを持つ古典的なツリー構造を持っています。私は、再帰的トラバーサルアプローチを使用することにより、深さレベルを得ることは非常に簡単ですが深さレベルでグループ化されたツリー構造のすべてのノードを収集する方法は?

nodes[ 
    ["A4"], 
    ["A3","B3"], 
    ["A2","B2","C2"], 
    ["A1","B1","C1"], 
    ["ROOT"] 
]; 

:さて、私はこのような(逆の順序でIE)最低レベルから始まる深さによってグループ化されたすべてのノードを収集したいと思いますBFSまたはDFS検索のツリートラバーサル中に深度レベルをすぐに取得する方法があるかどうか疑問に思います。

私はノードの挿入中に深さレベルを保存することができますが、私は多くの挿入と削除を行っているため、レベルごとに1つのショットでグループ化された構造全体を収集することをお勧めします。

また、私はBDSまたはDFSを使用することを好みません。どちらも問題ありません。ここに私の実際のコードは次のとおりです。

function Node(code, parent) { 
 
    this.code = code; 
 
    this.children = []; 
 
    this.parentNode = parent; 
 
} 
 
Node.prototype.addNode = function (code) { 
 
    var l = this.children.push(new Node(code, this)); 
 
    return this.children[l-1]; 
 
}; 
 
Node.prototype.dfs = function (leafCallback) { 
 
    var stack=[this], n, depth = 0; 
 
    while(stack.length > 0) { 
 
    n = stack.pop(); 
 
    if(n.children.length == 0) { 
 
     if(leafCallback) leafCallback(n, this); 
 
     continue; 
 
    } 
 
    for(var i=n.children.length-1; i>=0; i--) { 
 
     stack.push(n.children[i]); 
 
    } 
 
    depth++; // ??? 
 
    } 
 
}; 
 

 
var tree = new Node("ROOT"); 
 
tree.addNode("A1").addNode("A2").addNode("A3").addNode("A4"); 
 
tree.addNode("B1").addNode("B2").addNode("B3"); 
 
tree.addNode("C1").addNode("C2");

+0

が必要であることを指摘しmarvel308のおかげで 'depth'参照' .children'配列の '.length'していますか? – guest271314

+0

@ guest271314:申し訳ありません - もちろん、それはルートへのパスの長さです – deblocker

答えて

0

- 追加のヘルパーnode.depth

function Node(code, parent) { 
    this.code = code; 
    this.depth = -1; 
    this.children = []; 
    this.parentNode = parent; 
} 

Node.prototype.dfs= function() { 
    var result = [], stack = []; 
    this.depth = 0; 
    stack.push(this); 
    while(stack.length > 0) { 
    var n = stack[stack.length - 1], i = n.depth; 
    if(!result[i]) result.push([]); 
    result[i].push(n); /* get node or node.code, doesn't matter */ 
    stack.length--; 
    var children = n.children; 
    /* keep the original node insertion order, by looping backward */ 
    for(var j = n.children.length - 1; j >= 0; j--) { 
     var c = children[j]; 
     c.depth = n.depth + 1; 
     stack.push(c); 
    } 
    } 
    return result.reverse(); /* return an array */ 
}; 
1

function Node(code, parent) { 
 
    this.code = code; 
 
    this.children = []; 
 
    this.parentNode = parent; 
 
} 
 
Node.prototype.addNode = function (code) { 
 
    var l = this.children.push(new Node(code, this)); 
 
    return this.children[l-1]; 
 
}; 
 

 
let result = [], depth = {}; 
 
function dfs(node){ 
 
    node.depth = 0; 
 
    let stack = [node]; 
 
    while(stack.length > 0){ 
 
     let root = stack[stack.length - 1]; 
 
     let d = root.depth; 
 
     result[d] = result[d] || []; 
 
     result[d].push(root.code); 
 
     stack.length--; 
 
     for(let element of root.children){ 
 
      element.depth = root.depth + 1; 
 
      stack.push(element); 
 
     } 
 
    } 
 
} 
 

 
var tree = new Node("ROOT"); 
 
tree.addNode("A1").addNode("A2").addNode("A3").addNode("A4"); 
 
tree.addNode("B1").addNode("B2").addNode("B3"); 
 
tree.addNode("C1").addNode("C2"); 
 

 
dfs(tree); 
 

 
console.log(result.reverse());

0

をパラメータとしてあなたはこの中に記述することが可能である再帰とパッシングノードと深さを使用することができますテール最適化の恩恵を受ける再帰的方法

それだ
function reduceTree(tree) { 
    const getCode = n => n.code; 
    const _reduce = (level = [tree], acc = [[getCode(tree)]], depth = 1) => { 
     const children = level.reduce((a, e) => a.concat(e.children), []); 
     if (!children.length) { 
      return acc; 
     } 
     acc[depth] = children.map(getCode); 
     return _reduce(children, acc, depth + 1); 
    }; 
    return _reduce().reverse(); 
} 

reduceTree(tree); 
/* 
[ 
    ["A4"], 
    ["A3", "B3"], 
    ["A2", "B2", "C2"], 
    ["A1", "B1", "C1"], 
    ["ROOT"] 
] 
*/ 
関連する問題