我在树结构中有对象,我想从子节点聚合状态信息并用聚合状态更新父节点。假设节点A有子节点B1,B2,B1有C1,C2,C3作为子节点。每个节点都有一个status属性。
现在如果C1,C2,C3全部完成,那么我想将B1标记为已完成。如果C4,C5,C6,C7完成,则使B2完成。当B1和B2都完成时,标记A为完整。
我可以通过强力方法检查这些节点并进行更新,有人可以提出一种有效的算法来实现它。
A { B1 {C1,C2,C3}, B2 {C4,C5,C6,C7} }
答案 0 :(得分:3)
您需要进行后期遍历 - 首先访问节点的子节点,然后递归地标记节点本身。
像(伪代码):
iscomplete(node):
if node == Null:
return False
elsif no children:
return some "complete" value according to node value
else:
for child in node.children:
if not iscomplete(child):
return False
return True
答案 1 :(得分:2)
Eli Bendersky说得对,这个问题的一般答案是后序遍历。
为了提高效率,您必须使用您对此问题的所有了解。例如,如果您可以允许某些“陈旧性”,那么在每个节点中缓存complete
标志和时间戳可能会更好。
另一种可能性是节点的内部complete
状态很少发生变化。在这种情况下,传播向上完整性信息可能要好得多。这样的事情:
class NodeWithCompletenessInfo : public Node {
private bool internalComplete; // Am I personally done?
private bool childrenComplete; // Are my children done?
public bool isComplete() {
return internalComplete && childrenComplete;
}
public void markComplete() {
internalComplete = true;
if( isComplete() )
parent.markChildComplete();
}
public void markIncomplete() {
if( isComplete() )
parent.markChildIncomplete();
internalComplete = false;
}
private void markChildComplete() {
for( child in children ) {
if( !child.isComplete() )
return;
childrenComplete = true;
}
if( isComplete() )
parent.markChildComplete()
}
private void markChildIncomplete() {
if( isComplete() )
parent.markChildIncomplete();
this.childrenComplete = false;
}
}
答案 2 :(得分:1)
如果您知道哪些是叶子节点,那么
A {
B1
{C1, C2 = false, C3},
B2
{C4, C5=false, C6=false, C7}
} // those not marked false are true ;)
not_complete_leaf_nodes_with_different_parents = [ C2 , C5]
mark_not_complete(node):
node.complete = false
if parent != null
mark_not_complete(node.parent)
for each in not_complete_leaf_nodes_with_different_parents:
mark_not_complete(each.parent)
答案 3 :(得分:-1)