运行时检查二叉树是否是另一个二叉树的子树

时间:2016-08-28 17:37:51

标签: algorithm recursion tree asymptotic-complexity

我遇到了naive solution来检查二叉树是否是另一个二叉树的子树的问题:

给定两个二叉树,检查第一棵树是否是第二棵树的子树。树T的子树是由S中的节点及其在T中的所有后代组成的树S.对应于根节点的子树是整个树;与任何其他节点对应的子树称为适当的子树。

例如,在以下情况中,树S是树T的子树:

 Tree 2

      10  
    /    \ 
  4       6
   \
    30

    Tree 1
          26
        /   \
      10     3
    /    \     \
  4       6      3
   \
    30

解决方案是以预购方式遍历树T.对于遍历中的每个访问节点,查看以此节点为根的子树是否与S相同。

在帖子中说,算法在最坏的情况下具有n ^ 2或O(m * n)的运行时间,其中m和n是所涉及的两个树的大小。

这里的混淆点是,如果我们同时遍历两棵树,在最坏的情况下,你似乎只需要通过较大的树中的所有节点递归来找到子树。那么这个版本的算法(不是this one)如何具有二次运行时间?

2 个答案:

答案 0 :(得分:2)

好吧,基本上在isSubTree()函数中,你只遍历T树(主要树,而不是子树)。您对S不执行任何操作,因此在最坏的情况下,将对T中的每个节点执行此函数。然而(在最坏的情况下)每次执行时,它将检查areIdentical(T, S)是否在最坏的情况下必须完全遍历给定的一个树(直到其中一个为零)。

传递给areIdentical()函数的树明显越来越小,但在这种情况下,如果涉及时间复杂度则无关紧要。无论哪种方式,这都会为您提供O(n^2)O(n*m)(其中nm - 这些树中的节点数量。)

答案 1 :(得分:0)

为了合理地解决问题,将两棵树弄平。使用Lisp表示法, 我们得到

(10 (4(30) (6))

(26 (10 (4(30) (6)) (3 (3))

因此子树是父节点的子串。使用strstr我们可以 通常在O(N)时间内完成,可能需要更长的时间 如果我们有很多很多附近的子树。您可以使用后缀 如果你需要进行大量搜索并将其降低到O(M) 时间,其中M是子树的大小。

但实际上运行时并没有改善。它的算法相同, 例如,如果所有的树都会有N M行为 具有相同的节点ID和结构,除了最右边 查询子树的子节点。它只是操作 变得更快。