我按如下方式构建节点对象的Tree结构:
function Node(parent) {
this.parent = parent;
this.selected = false;
this.children = [];
}
Node.prototype.addChild = function () {
var l = this.children.push(new Node(this));
return this.children[l-1];
};
Node.prototype.bfs = function(callback) {
var queue=[this], n;
while(queue.length > 0) {
n = queue.shift();
callback(n);
if(n.children.length == 0) continue;
for (var i = 0; i< n.children.length; i++) {
queue.push(n.children[i]);
}
}
};
var root = new Node(null);
var nodeA = root.addChild();
var nodeB = root.addChild();
var nodeAA = nodeA.addChild();
var nodeAB = nodeA.addChild();
var nodeBA = nodeB.addChild();
var nodeBB = nodeB.addChild();
现在,我选择了一些节点:
nodeAA.selected = true;
我能够通过BFS找到所选节点:
root.bfs(function(node){
console.log(node, node.selected);
});
...并且很容易标记为选择所有相应的父节点,直到根:
var n = node;
do {
n.selected = true;
n = n.parentNode;
} while (n);
现在,我需要使用选定的叶子和相应的父节点创建初始Tree结构的克隆,但是我无法将新的子节点重新分配给各自的新父节点。
尝试使用JSON.stringify()会导致循环引用错误。
如何只使用选定叶子的分支重建我的初始树的克隆?
答案 0 :(得分:0)
假设可以修剪现有树以排除未选择的叶子路径,In [591]: tidx = pd.date_range('2017-01-01', periods=12, freq='MS')
In [592]: (df.set_index(['Month', 'User'])['count'].unstack()
.reindex(tidx)
.fillna(0)
.unstack().reset_index()
.rename(columns={'level_1': 'Month', 0: 'count'}))
Out[592]:
User Month count
0 A 2017-01-01 2.0
1 A 2017-02-01 0.0
2 A 2017-03-01 2.0
3 A 2017-04-01 0.0
4 A 2017-05-01 2.0
5 A 2017-06-01 0.0
6 A 2017-07-01 0.0
7 A 2017-08-01 0.0
8 A 2017-09-01 2.0
9 A 2017-10-01 0.0
10 A 2017-11-01 0.0
11 A 2017-12-01 0.0
12 B 2017-01-01 5.0
13 B 2017-02-01 0.0
14 B 2017-03-01 0.0
15 B 2017-04-01 0.0
16 B 2017-05-01 5.0
17 B 2017-06-01 0.0
18 B 2017-07-01 0.0
19 B 2017-08-01 0.0
20 B 2017-09-01 0.0
21 B 2017-10-01 0.0
22 B 2017-11-01 0.0
23 B 2017-12-01 0.0
将执行此操作。
缺点:
dfs
值的children数组中的条目存在。可以通过使用支持null
删除和插入Psuedo Code
O(1)
假设是这样的。
Prune-UnSelected-Leaf(root) if(root) == null return null if(root.children.length == 0) //Check if node is a Leaf if(root.selected) return root // Keep this node else return null; // Ignore the node bool AnyChildSelected = false for(i : 1 to children.Length) var childSelectedNode = Prune-UnSelected-Leaf(children[i]) if(childSelectedNode) AnyChildSelected = true root.children[i] = childSelectedNode if(AnyChildSelected == true || node.selected == true) // Keep the node return node else return null; // Ignore the node
运行算法后,未选择的路径将设置为null,并且看起来像这样
Root Node / | \ / | \ A(T) B(F) C(F) / / D(F) E(T)
您还可以修改上述算法以克隆树,而无需修改现有树。
重载 Root Node
/ X \
Return A / X(null) \ Return C
A(T) B(F) C(F)
X /
X Return null / Return E
D(F) E(T)
以将现有子节点附加到父
addChild
让addChild(child)
child.parent = this
l = this.children.push(child);
return this.children[l-1];
成为一个函数,它接受一个节点并使用与该节点相关的信息创建一个深层副本,但初始化Clone-Node(node)
,parent
和children
的空/默认值属性
selected