如何找出两个二进制树在内容方面是否相同?

时间:2016-02-07 23:21:56

标签: algorithm binary-tree

我看到几篇关于如何确定两棵树的结构是否相同的帖子,但没有找到关于如何找到两棵树在内容方面相同的答案。

比如说,树节点定义如下。

TreeNode {
    string data;
    TreeNode* left;
    TreeNode* right
};

现在我有两个二叉树,需要找出两个树在内容方面是否相同。这两个可能在结构上不相同,也不能假设数据字符串在单词中是相同的。

例如,我们可能有两棵树。当我们进行顺序步行时,这两棵树在内容上可以被视为相同。需要说明的是,当我们连接这两棵树中的所有节点字符串时,它们是相同的。即abcdedfg

 (abc)
 |   \
 (d) (efg)

 (a)
 |  \
 (b) (cdefg)

我知道我们可以通过步骤来收集两棵树的所有字符串,我们可以比较得到的两个字符串,但我想知道是否有更有效的方法来比较两棵树,不管怎样走两棵树并行或创建迭代器。这些对我来说似乎都不是很明显,所以想得到一些反馈,也许还有一些代码片段可以获得更好的想法。

提前致谢。

5 个答案:

答案 0 :(得分:1)

解决方案是编写生成器,逐个生成排序元素中的字母。这比一次生成所有字母更快,因为例如可以检测到树与第一个字母不同,并且在这种情况下它不会比较剩余的字母。在Python中,这将是:

def iter_bin_tree_letters(tree):
    if tree.left:
        for letter in iter_bin_tree_letters(tree.left)
            yield letter
    # RETURN ITERATOR OVER LETTERS  <----------
    for letter in tree.data:
        yield letter
    if tree.right:
        for letter in iter_bin_tree_letters(tree.right)
            yield letter

现在只需比较两个生成器的结果,直到找到2个不同的元素或用完元素:

def are_equal_bin_trees(tree1, tree2):
    t1 = iter_bin_tree_letters(tree1)
    t2 = iter_bin_tree_letters(tree2)
    t1_empty = False
    while True:
        try:
            e1 = t1.next()
        except:
            t1_empty = True
        try:
            e2 = t2.next()
        except:
           if not t1_empty:
               return False
           return True
        if e1!=e2:
             return False

这是最快的算法,在最坏的情况下它具有min(n,m)的时间复杂度。

答案 1 :(得分:1)

您可以使用DFS(深度优先搜索)迭代两个树,逐个字符地比较。这也可以与双指算法结合使用,您可以根据您所处的元素以不同的速度遍历每棵树的节点。

从你的例子开始。树1和树,其中节点X-Y是行X,元素Y.树1节点2-2是“efg”:

Tree 1
(abc)
 |   \
 (d) (efg)

Tree 2
 (a)
 |  \
 (b) (cdefg)

算法将依次遍历每棵树的节点,逐个字符地进行比较。

  1. 树1节点1-1
  2. 开始
  3. 树2节点1-1
  4. 开始
  5. 将a1与a2
  6. 进行比较
  7. 前进到树2节点2-1
  8. 将b1与b2进行比较
  9. 前进至树2节点2-2
  10. 将c1与c2进行比较
  11. 前进到树1节点2-1
  12. 将d1与d2进行比较
  13. 前进到树1节点2-2
  14. 将e1与e2进行比较
  15. 将f1与f2进行比较
  16. 将g1与g2进行比较
  17. 返回相同!

答案 2 :(得分:0)

您似乎必须枚举两棵树中的所有节点,以查看它们是否具有不同的内容。

除非您遍历树中的所有节点,否则无法知道节点是否在树中。例如

 a      a
b c    c d

您会在两次传递中看到abac。您不知道树1是否包含c或树2包含b,除非您遍历两棵树的全部。

在迭代过程中,您可以将每个节点放在一个单独的优先级队列中,并在队列顶部弹出值,直到您弹出的值不相等为止。这使得您的平均情况比使用普通队列快得多,因为树中每个节点的log(n)插入的启发式开销。

答案 3 :(得分:0)

散列两个数据结构或使用朴素的o(n)算法进行比较。每个数据结构都可以表示为字节流。是的,在这种情况下使用指针是一个问题,应该避免使用。

我假设树是由相同的算法生成的,因此不能有两个具有相同内容的不同树。

答案 4 :(得分:0)

我们可以先在数组中存储两棵树的遍历 - 成本O(n) 现在我们遍历两个数组并对所有元素执行XOR,如果是异或的话 为零然后它们是相同的,否则不相同 - 成本O(n) 所以我们可以在O(n)中做。