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

时间:2014-06-30 21:45:26

标签: algorithm data-structures

要检查二叉树是否是另一棵树的子树,我想是允许将树的inorder和preorder遍历存储为字符串(比如为每个节点分配字符),然后执行子字符串匹配以检查树是否是否是子树。这种方法会起作用吗?

3 个答案:

答案 0 :(得分:-1)

不确定谁选择@ genisage的答案是正确的。顺序预订/后序子串方法是解决此问题的最佳方案。在示例中,@ genisage提到预先遍序的遍历是1 2和2 2 1. 1 2不是2 2 1的子字符串,答案是假的。

答案 1 :(得分:-2)

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

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

    Tree S
      10  
    /    \ 
  4       6
   \
    30


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

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

#include <stdio.h>
#include <stdlib.h>

/* A binary tree node has data, left child and right child */
struct node
{
    int data;
    struct node* left;
    struct node* right;
};

/* A utility function to check whether trees with roots as root1 and root2 are identical or not */
bool areIdentical(struct node * root1, struct node *root2)
{
    /* base cases */
    if(root1 == NULL && root2 == NULL)
        return true;

    if(root1 == NULL || root2 == NULL)
        return false;

    /* Check if the data of both roots is same and data of left and right subtrees are also same */
    return (root1->data == root2->data   &&
        areIdentical(root1->left, root2->left) &&
        areIdentical(root1->right, root2->right) );
}


/* This function returns true if S is a subtree of T, otherwise false */
bool isSubtree(struct node *T, struct node *S)
{
    /* base cases */
    if (S == NULL)
        return true;

    if (T == NULL)
        return false;

    /* Check the tree with root as current node */
    if (areIdentical(T, S))
        return true;

    /* If the tree with root as current node doesn't match then
   try left and right subtrees one by one */
    return isSubtree(T->left, S) ||
       isSubtree(T->right, S);
}


/* Helper function that allocates a new node with the given data
   and NULL left and right pointers. */
struct node* newNode(int data)
{
    struct node* node = (struct node*)malloc(sizeof(struct node));
    node->data  = data;
    node->left  = NULL;
    node->right = NULL;
    return(node);
}

/* Driver program to test above function */
int main()
{
    /* Construct the following tree
          26
        /   \
      10     3
    /    \     \
  4      6      3
   \
    30
*/
    struct node *T        = newNode(26);
    T->right              = newNode(3);
    T->right->right       = newNode(3);
    T->left               = newNode(10);
    T->left->left         = newNode(4);
    T->left->left->right  = newNode(30);
    T->left->right        = newNode(6);

/* Construct the following tree
      10
    /    \
  4      6
   \
    30
*/
    struct node *S    = newNode(10);
    S->right          = newNode(6);
    S->left           = newNode(4);
    S->left->right    = newNode(30);


    if( isSubtree(T, S) )
        printf("Tree S is subtree of tree T");
    else
        printf("Tree S is not a subtree of tree T");

    getchar();
    return 0;
}

Output: Tree S is subtree of tree T

答案 2 :(得分:-2)

不,它不会。考虑一个可能的子树,它包含一个包含1的根节点和一个包含2的左子节点。另一个树包含根1,左子2和右子1。

很明显,第一个不是第二个的子树,但是你的方法会说它是因为前序遍历是1 2和1 2 1,并且inorder遍历是2 1和2 1 1。

当遇到区分时,你需要添加空值,使前序遍历1 2为空,1 2 1和inorder 2 1为null,2 1 1为非子树。