我有一个可能很大的根树结构,我希望将其转换为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,因此它不平衡,可能有两个以上子节点。
答案 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)
中运行上面的算法。虽然它会提供更好的渐近复杂度,但我怀疑它实际上会更快。