2

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

M i,j = {0如果叶子i有祖先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 片叶子),我想知道是否有一种比遍历每个叶子节点的树更智能/更快的方法。感觉好像某种算法在这个问题的某个地方,但我还没有弄清楚。也许有人可以帮忙?

在我的应用程序中,这棵树代表大的系统发育层次结构,因此它不平衡,并且可能有两个以上子节点的节点。

4

1 回答 1

1

我会使用后序遍历。

在遍历树时维护叶子列表,并且在每个级别中 - 该列表将包含此级别之前的所有叶子。

我们将使用的函数的声明:

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)初始化,可以在 中初始化矩阵O(1),然后在 中运行上述算法O(nlogn)。虽然它会提供更好的渐近复杂性,但我怀疑它实际上会更快。

于 2012-09-05T08:35:32.197 回答