如何让所有父母快速到达树上的所有树叶?

时间:2012-09-05 07:40:20

标签: algorithm data-structures tree graph-algorithm

我有一个可能很大的根树结构,我希望将其转换为X * Y矩阵,其中X是树中叶子的数量,Y是节点中的节点数量度数大于1的树,即根节点和内部节点。矩阵应该这样填充:

如果叶0有祖先i,则

M i,j = {j,否则为1

例如,这棵树:

      --A 
     /
    1   B
   / \ /
  /   3  
 /     \
0       C
 \ 
  \   --D
   \ /
    2
     \--E

会转化为这个矩阵:

  0 1 2 3
A T T F F
B T T F T
C T T F T
D T F T F
E T F T F

由于树可能会变得很大(可能大约有100,000个叶子),我想知道是否有更聪明/更快的方法,而不是遍历每个叶子节点的树。感觉某种算法在某个地方存在这个问题,但我还没想到它。也许有人可以提供帮助?

在我的应用程序中,树代表大phylogenetic hierarchies,因此它不平衡,可能有两个以上子节点。

1 个答案:

答案 0 :(得分:1)

我选择订购后遍历。

在遍历树时保持叶子列表,在每个级别中 - 列表将包含到达此级别的所有叶子。

我们将使用的函数的decalrations:

list merge(list1,list2) //merges two lists and creates a new list
list create() // creates a new empty list
void add(list,e) // appends e to the list
void setParent(leaf,node) //sets (in your matrix) node as a parent of leaf

伪码:

list Traverse(root):
  if (root == nil):
      l <- create()
      return l
  else if (root is leaf):
      l <- create()
      add(l,root)
      return l
  else: 
      l1 <- Traverse(root.left)
      l2 <- Traverse(root.right)
      l <- merge(l1,l2)
      for each leaf in l:
          setParent(leaf,root)
      return l

时间是O(n*m) - 用于设置矩阵(尽管算法本身对于平衡树来说是O(nlogn)时间。)

如果您想阻止O(n*m)初始化,可以initialize the matrix in O(1),然后在O(nlogn)中运行上面的算法。虽然它会提供更好的渐近复杂度,但我怀疑它实际上会更快。