当前位置: 首页 > 知识库问答 >
问题:

如何快速获得一棵树上所有叶子的所有亲本?

栾景胜
2023-03-14

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

mi, 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片叶子),我想知道是否有一种比为每个叶子节点遍历树更聪明/更快的方法。感觉某种算法在某个地方遇到了这个问题,但我还没有弄清楚。也许有人可以帮忙?

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

共有1个答案

高宏峻
2023-03-14

我会选择后序遍历。

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

我们将使用的函数的贴花:

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

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

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

 类似资料:
  • 假设我在一棵树中有一个节点,我如何获得所有的叶节点,它们的祖先是这个节点?我这样定义了TreeNode:

  • 给定一棵二叉树,问题是找到所有根到叶的路径。我们通过以列表的形式传递路径,并在到达叶子时将其添加到结果中来了解算法。 我的问题是存储所有路径需要多少空间。我的直觉是,每条路径将消耗树高度(O(h))的内存顺序,如果我们的完整二叉树中有2*n-1个节点,那么每个节点对应于一条路径,因此假设树高度平衡,空间复杂度将为O(n*log(n))。我的分析正确吗?

  • 问题内容: 表-用户 列-(userId,name,managerId) 行- 如果我提供用户ID,则应列出所有向他报告的人。如果我给userId = 2,则应返回3,4。 这个查询正确吗 有什么有效的方法来管理DB中的树结构吗?左右叶方式怎么样? 问题答案: 在我看来,邻接列表模型的问题在于,在SQL中很难处理它,尤其是当您不知道树结构的嵌套深度时。 您提到的“左右叶方式”可能是嵌套集合模型,它

  • 所以我有两到三棵树,它们是在执行一些代码时生成的。此树的每个节点都有一个属性,即它至少有0个子节点,最多有8个子节点。我猜你可以得到这样一个完整的树的图片,在0级有一个根节点。在1级8个节点在2级64个节点,以此类推。父节点的每个子节点的编号从0到7,我在java中将其存储为字节整数类型,顺便说一句,我在java中实现了这一点。 现在我需要合并这两到三棵树,我已经生成,我这样做的水平明智完全不考虑

  • 问题内容: 我想知道实时有多少用户连接到我的应用程序。我想到了要打开的会话数循环的想法,但是我找不到该怎么做的方法。如果您有另一种方法可以提出您的建议。 问题答案: 到目前为止,我发现的最佳解决方案是计算会话的创建和销毁时间。 然后在VaadinServlet init()方法中添加SessionListeners

  • 你好,我一直在尝试自动化监控一个站点,但它“响应”多个文档,我想知道如何浏览他们或选择哪一个我想要分析。 代码非常简单: 站点这样“回应”: 它不允许我发布图片,但这里有链接: 如何选择不同的单据而不是第一个单据?