如何收集树结构的所有节点,按深度级别分组?

时间:2017-09-24 08:33:04

标签: javascript tree depth-first-search breadth-first-search

我有一个带有子节点和父节点的经典树结构。现在,我想收集从最低级别(即以相反顺序)开始按深度分组的所有节点,如下所示:

.as-console-wrapper { max-height: 100% !important; top: 0; }

虽然通过使用递归遍历方法获得深度级别非常容易,但我想知道是否有任何方法可以在BFS或DFS搜索中的树遍历期间立即获得深度级别。

我知道我可以在节点插入期间存储深度级别,但是由于我正在进行大量的插入和删除,我宁愿一次性收集按级别分组的整个结构。

另外,我根本不喜欢使用BDS或DFS,两者都很好。这是我的实际代码:

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

3 个答案:

答案 0 :(得分: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());

答案 1 :(得分:0)

可以以递归的方式编写它,这将受益于尾部优化

nosetests

答案 2 :(得分:0)

这就是它 - 感谢marvel308指出需要一个额外的助手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 */
};