Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何收集树结构中按深度级别分组的所有节点?_Javascript_Tree_Depth First Search_Breadth First Search - Fatal编程技术网

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

Javascript 如何收集树结构中按深度级别分组的所有节点?,javascript,tree,depth-first-search,breadth-first-search,Javascript,Tree,Depth First Search,Breadth First Search,我有一个带有child和父节点的经典树结构。现在,我想从最低级别开始收集按深度分组的所有节点(即按相反顺序),如下所示: nodes[ ["A4"], ["A3","B3"], ["A2","B2","C2"], ["A1","B1","C1"], ["ROOT"] ]; 虽然使用递归遍历方法获取深度级别非常容易,但我想知道是否有任何方法可以在BFS或DFS搜索中的树遍历期间立即获取深度级别 我知道我可以在节点插入期间存储深度级别,但由于我正在进行大量的插入和删除操作,我更

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

nodes[
  ["A4"],
  ["A3","B3"],
  ["A2","B2","C2"],
  ["A1","B1","C1"],
  ["ROOT"]
];
虽然使用递归遍历方法获取深度级别非常容易,但我想知道是否有任何方法可以在BFS或DFS搜索中的树遍历期间立即获取深度级别

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

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

功能节点(代码,父节点){
this.code=代码;
这是:children=[];
this.parentNode=父节点;
}
Node.prototype.addNode=函数(代码){
var l=this.children.push(新节点(代码,this));
归还这个。儿童[l-1];
};
Node.prototype.dfs=函数(leafCallback){
var stack=[this],n,depth=0;
while(stack.length>0){
n=stack.pop();
如果(n.children.length==0){
if(leafCallback)leafCallback(n,this);
继续;
}
对于(变量i=n.children.length-1;i>=0;i--){
堆栈推送(n.children[i]);
}
深度++;/???
}
};
变量树=新节点(“根”);
tree.addNode(“A1”).addNode(“A2”).addNode(“A3”).addNode(“A4”);
tree.addNode(“B1”).addNode(“B2”).addNode(“B3”);

树.addNode(“C1”).addNode(“C2”)您可以使用递归和传递节点和深度作为参数

功能节点(代码,父节点){
this.code=代码;
这是:children=[];
this.parentNode=父节点;
}
Node.prototype.addNode=函数(代码){
var l=this.children.push(新节点(代码,this));
归还这个。儿童[l-1];
};
让结果=[],深度={};
函数dfs(节点){
node.depth=0;
让堆栈=[node];
while(stack.length>0){
设root=stack[stack.length-1];
设d=根深度;
结果[d]=结果[d]| |[];
结果[d]。推送(root.code);
堆栈长度--;
for(root.children的let元素){
element.depth=root.depth+1;
堆栈推送(元素);
}
}
}
变量树=新节点(“根”);
tree.addNode(“A1”).addNode(“A2”).addNode(“A3”).addNode(“A4”);
tree.addNode(“B1”).addNode(“B2”).addNode(“B3”);
树.addNode(“C1”).addNode(“C2”);
dfs(tree);

log(result.reverse())可以用递归方式编写,这将受益于尾部优化

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"]
]
*/

就是这样-感谢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 */
};

depth
是否引用了
.children
数组的
.length