【发布时间】:2017-10-02 08:12:02
【问题描述】:
在最简单的情况下,我有两棵树(有向图),每个树节点都有一个唯一的 id 并且可以有多个子节点,其中第二棵树的所有叶子都包含在第一棵树的叶子中。基于叶子,我想将第一棵树分成两棵树,这样新的第一棵树将不包含原始第二棵树的任何叶子,而新的第二棵树将包含原始第二棵树的所有叶子。诀窍还在于,如果一个节点的所有子节点都将被移动到新的第二棵树,那么该节点本身也应该被移动。
例如对于这样的两棵树作为输入:
- 1(第一棵树的根)
- 11
- 111
- 1111
- 11111
- 11112
- 1112
- 11121
- 11122
- 1111
- 112
- 11201
- 11202
- 111
- 12
- 121
- 12101
- 12102
- 122
- 12201
- 12202
- 121
- 11
- 2(第二棵树的根)
- 21
- 211
- 2111
- 11112
- 2111
- 212
- 11201
- 11202
- 211
- 21
我希望得到两棵新树,这样:
- 1(新的第一棵树的根)
- 11
- 111
- 1111
- 11111
- 1112
- 11121
- 11122
- 1111
- 111
- 12
- 121
- 12101
- 12102
- 122
- 12201
- 12202
- 121
- 11
- 2(新的第二棵树的根)
- 21
- 211
- 2111
- 11112
- 2111
- 112(从原始第一棵树复制的节点导致其所有子节点都被复制)
- 11201
- 11202
- 211
- 21
实现这一目标的最佳方法(算法)是什么?
从第一棵树中删除节点很简单,但是我有问题如何构造第二棵树,并在合适的地方重用第一棵树的节点。
我正在尝试在 Java 1.7 版中实现这种拆分(我不能使用 1.8)。
编辑
我能够想出一个解决方案,在下面的答案中提供更详细的信息,但如果有人能提供更好的解决方案,我也会很高兴 :)
【问题讨论】:
-
您似乎想到了某种编程语言的特定实现。我们需要知道哪一个(程序性的、带有指针的等),否则我们将无法提供帮助,因为对您的问题的简单回答是:您已经有了树 2。
-
你怎么知道节点 112 最终是节点 21 的子节点?如果这一层有节点 22 和 23,为什么不添加其中任何一个呢?
-
@Vroomfondel 我在 Java 1.6 中实现了这一点,添加了指向 BitBucket 上示例代码的链接。
-
@fafl 在原始树中,有一个节点 212 与 112 具有相同的子节点,这就是为什么这个节点应该被替换,但它的父节点保持不变。