【问题标题】:Tree splitting(extracting) algorithm树分裂(提取)算法
【发布时间】:2017-10-02 08:12:02
【问题描述】:

在最简单的情况下,我有两棵树(有向图),每个树节点都有一个唯一的 id 并且可以有多个子节点,其中第二棵树的所有叶子都包含在第一棵树的叶子中。基于叶子,我想将第一棵树分成两棵树,这样新的第一棵树将不包含原始第二棵树的任何叶子,而新的第二棵树将包含原始第二棵树的所有叶子。诀窍还在于,如果一个节点的所有子节点都将被移动到新的第二棵树,那么该节点本身也应该被移动。

例如对于这样的两棵树作为输入:

  • 1(第一棵树的根)
    • 11
      • 111
        • 1111
          • 11111
          • 11112
        • 1112
          • 11121
          • 11122
      • 112
        • 11201
        • 11202
    • 12
      • 121
        • 12101
        • 12102
      • 122
        • 12201
        • 12202
  • 2(第二棵树的根)
    • 21
      • 211
        • 2111
          • 11112
      • 212
        • 11201
        • 11202

我希望得到两棵新树,这样:

  • 1(新的第一棵树的根)
    • 11
      • 111
        • 1111
          • 11111
        • 1112
          • 11121
          • 11122
    • 12
      • 121
        • 12101
        • 12102
      • 122
        • 12201
        • 12202
  • 2(新的第二棵树的根)
    • 21
      • 211
        • 2111
          • 11112
      • 112(从原始第一棵树复制的节点导致其所有子节点都被复制)
        • 11201
        • 11202

实现这一目标的最佳方法(算法)是什么?

从第一棵树中删除节点很简单,但是我有问题如何构造第二棵树,并在合适的地方重用第一棵树的节点。

我正在尝试在 Java 1.7 版中实现这种拆分(我不能使用 1.8)。

编辑

我能够想出一个解决方案,在下面的答案中提供更详细的信息,但如果有人能提供更好的解决方案,我也会很高兴 :)

【问题讨论】:

  • 您似乎想到了某种编程语言的特定实现。我们需要知道哪一个(程序性的、带有指针的等),否则我们将无法提供帮助,因为对您的问题的简单回答是:您已经有了树 2。
  • 你怎么知道节点 112 最终是节点 21 的子节点?如果这一层有节点 22 和 23,为什么不添加其中任何一个呢?
  • @Vroomfondel 我在 Java 1.6 中实现了这一点,添加了指向 BitBucket 上示例代码的链接。
  • @fafl 在原始树中,有一个节点 212 与 112 具有相同的子节点,这就是为什么这个节点应该被替换,但它的父节点保持不变。

标签: java algorithm tree


【解决方案1】:

我想出了一个解决问题的方法,也许它对某人有用。我的算法如下:

  1. 我们将第一个原始树称为源树,将第二个原始树称为掩码树。
  2. 将树转换为所有原始树及其父级的叶子列表。
  3. 遍历叶子列表并从叶子父节点重建树。
    • 掩码树中的父级比源树中的父级具有更高的优先级
    • 对于掩码树父母,将源树父母注册为可能的替代品
  4. 迭代可能的替换,如果替换没有在任何树中使用,则用它替换节点。

不确定我是否说得足够清楚。如果没有,请检查 BitBucket TreeSplitter 上可用的植入。

此解决方案可能不是最佳的,因此如果您有更好的方法,请将其发布为答案。

【讨论】:

    猜你喜欢
    • 2014-08-14
    • 1970-01-01
    • 2018-09-27
    • 2016-08-18
    • 2011-09-11
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多