树分裂(提取)算法

时间:2017-10-02 08:12:03

标签: java algorithm tree

在最简单的情况下,我有两个树(有向图),每个树节点都有一个唯一的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)。

修改

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

1 个答案:

答案 0 :(得分:0)

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

  1. 让我们将第一个原始树称为源树,将第二个原始树称为掩码树。
  2. 将树转换为叶子列表,其父亲来自所有原始树木。
  3. 迭代叶子列表并从叶子父母重建树木。
    • 来自掩码树的父母对源头树的父母有更高的优先权
    • 用于掩码树父级注册源树父级作为可能的替换
  4. 迭代可能的替换,如果没有在任何树中使用替换,则用它替换节点。
  5. 不确定我是否说得够清楚。如果没有检查BitBucket TreeSplitter上可用的implamantation。

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