在相同的节点上合并两棵树

时间:2014-07-28 21:26:15

标签: algorithm language-agnostic tree

当ID相等时,节点相等。一棵树中的ID是唯一的。在模式上,节点的ID是可见的。

考虑tree1

root
  |
  +-- CC
  |   |
  |   \-- ZZZ
  |        |
  |        \-- UU
  |
  \-- A
      |
      \-- HAH

tree2

root
  |
  +-- A
      |
      +-- ADD
      |
      \-- HAH   

我希望merge(tree1, tree2)能够这样做:

root
  |
  +-- CC
  |   |
  |   \-- ZZZ
  |        |
  |        \-- UU
  |
  \-- A
      |
      +-- HAH
      |
      \-- ADD

怎么做?

节点有典型的方法,如getParent()getChildren()

孩子的顺序无关紧要。所以,结果也可能是:

root
  |
  +-- A
  |   |
  |   +-- ADD
  |   |
  |   \-- HAH
  |
  \-- CC
     |
     \-- ZZZ
          |
          \-- UU

2 个答案:

答案 0 :(得分:1)

基本算法并不难:

def merge_trees (t1, t2):
  make_tree(map(merge_trees,assign(getChildren(t1),getChildren(t2),tree_similarity)))
  • make_tree(children):使用给定的子项列表创建一个树
  • map(f,list):在f的每个元素上调用函数list并返回返回值列表
  • assign(list1,list2,cost_function):实现Hungarian algorithm,返回匹配对的列表

诀窍在于定义tree_similarity,它必须递归调用assign

实际上,高效的实现必须缓存assign调用的返回值。

答案 1 :(得分:1)

我的伪代码命题。评论非常受欢迎。

merge(tree1, tree2) {
    for (node : tree2.bfs()) { // for every node in breadth-first traversal order
        found = tree1.find(node.getParent());     // find parent in tree1
        if (found == null)                        // no parent?
            continue;                             // skip it, it's root
        if (!found.getChildren().contains(node))  // no node from tree2 in tree1?
            found.add(node);                      // add it
    }
    return tree1;
}