从子树节点聚合值的算法

时间:2010-03-24 17:18:22

标签: java algorithm

我在树结构中有对象,我想从子节点聚合状态信息并用聚合状态更新父节点。假设节点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}   }

4 个答案:

答案 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)

我看不出你能逃避“蛮力”。

我会使用访客设计模式。

http://www.javaworld.com/javaworld/javatips/jw-javatip98.html

http://sourcemaking.com/design_patterns/visitor