Check if a binary tree is subtree of another binary tree

来源:互联网 发布:最小公倍数算法流程图 编辑:程序博客网 时间:2024/05/02 03:08

Given two binary trees, check if the first tree is subtree of the second one. A subtree of a tree T is a tree S consisting of a node in T and all of its descendants in T.

The subtree corresponding to the root node is the entire tree; the subtree corresponding to any other node is called a proper subtree.

For example, in the following case, Tree1 is a subtree of Tree2.

        Tree1          x         /    \      a       b       \        c        Tree2              z            /   \          x      e        /    \     \      a       b      k       \        c

We have discussed a O(n2) solution for this problem. In this post a O(n) solution is discussed. The idea is based on the fact that inorder and preorder/postorder uniquely identify a binary tree. Tree S is a subtree of T if both inorder and preorder traversals of S arew substrings of inorder and preorder traversals of T respectively.

Following are detailed steps.

1) Find inorder and preorder traversals of T, store them in two auxiliary arrays inT[] and preT[].

2) Find inorder and preorder traversals of S, store them in two auxiliary arrays inS[] and preS[].

3) If inS[] is a subarray of inT[] and preS[] is a subarray preT[], then S is a subtree of T. Else not.

We can also use postorder traversal in place of preorder in the above algorithm.

Let us consider the above example

Inorder and Preorder traversals of the big tree are.inT[]   =  {a, c, x, b, z, e, k}preT[]  =  {z, x, a, c, b, e, k}Inorder and Preorder traversals of small tree areinS[]  = {a, c, x, b}preS[] = {x, a, c, b}We can easily figure out that inS[] is a subarray ofinT[] and preS[] is a subarray of preT[]. 

EDIT

The above algorithm doesn't work for cases where a tree is presentin another tree, but not as a subtree. Consider the following example.        Tree1          x         /    \      a       b     /            c                 Tree2          x         /    \      a       b     /         \    c            dInorder and Preorder traversals of the big tree or Tree2 are.Inorder and Preorder traversals of small tree or Tree1 areThe Tree2 is not a subtree of Tree1, but inS[] and preS[] aresubarrays of inT[] and preT[] respectively.

The above algorithm can be extended to handle such cases by adding a special character whenever we encounter NULL in inorder and preorder traversals. Thanks to Shivam Goel for suggesting this extension.

Following is C++ implementation of above algorithm.

#include <iostream>
#include <cstring>
usingnamespace std;
#define MAX 100
 
// Structure of a tree node
structNode
{
    charkey;
    structNode *left, *right;
};
 
// A utility function to create a new BST node
Node *newNode(charitem)
{
    Node *temp = new Node;
    temp->key = item;
    temp->left = temp->right = NULL;
    returntemp;
}
 
// A utility function to store inorder traversal of tree rooted
// with root in an array arr[]. Note that i is passed as reference
voidstoreInorder(Node *root, chararr[], int&i)
{
    if(root == NULL)
    {
        arr[i++] ='$';
        return;
    }
    storeInorder(root->left, arr, i);
    arr[i++] = root->key;
    storeInorder(root->right, arr, i);
}
 
// A utility function to store preorder traversal of tree rooted
// with root in an array arr[]. Note that i is passed as reference
voidstorePreOrder(Node *root, chararr[], int&i)
{
    if(root == NULL)
    {
        arr[i++] ='$';
        return;
    }
    arr[i++] = root->key;
    storePreOrder(root->left, arr, i);
    storePreOrder(root->right, arr, i);
}
 
/* This function returns true if S is a subtree of T, otherwise false */
boolisSubtree(Node *T, Node *S)
{
    /* base cases */
    if(S == NULL)  returntrue;
    if(T == NULL)  returnfalse;
 
    // Store Inorder traversals of T and S in inT[0..m-1]
    // and inS[0..n-1] respectively
    intm = 0, n = 0;
    charinT[MAX], inS[MAX];
    storeInorder(T, inT, m);
    storeInorder(S, inS, n);
    inT[m] ='\0', inS[n] ='\0';
 
    // If inS[] is not a substring of preS[], return false
    if(strstr(inT, inS) == NULL)
        returnfalse;
 
    // Store Preorder traversals of T and S in inT[0..m-1]
    // and inS[0..n-1] respectively
    m = 0, n = 0;
    charpreT[MAX], preS[MAX];
    storePreOrder(T, preT, m);
    storePreOrder(S, preS, n);
    preT[m] ='\0', preS[n] ='\0';
 
    // If inS[] is not a substring of preS[], return false
    // Else return true
    return(strstr(preT, preS) != NULL);
}
 
// Driver program to test above function
intmain()
{
    Node *T = newNode('a');
    T->left = newNode('b');
    T->right = newNode('d');
    T->left->left = newNode('c');
    T->right->right = newNode('e');
 
    Node *S = newNode('a');
    S->left = newNode('b');
    S->left->left = newNode('c');
    S->right = newNode('d');
 
    if(isSubtree(T, S))
        cout <<"Yes: S is a subtree of T";
    else
        cout <<"No: S is NOT a subtree of T";
 
    return0;
}

Output:

No: S is NOT a subtree of T

Time Complexity: Inorder and Preorder traversals of Binary Tree take O(n) time. The functionstrstr() can also be implemented in O(n) time using KMP string matching algorithm.

Auxiliary Space: O(n)

Thanks to Ashwini Singh for suggesting this method. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电脑刺激战场卡怎么办 grub 文件兼容性错误怎么办 电脑程序不兼容怎么办 运行程序不兼容怎么办 usb驱动删了怎么办 电脑卡死 点不开怎么办 电脑开机找不到驱动程序怎么办 显卡关了黑屏怎么办 xp全部程序打不开怎么办 七彩凤电脑打不开怎么办 鹦鹉鱼不敢吃食怎么办 甘油三酯1.87怎么办 手机移动数据网打不开怎么办 苹果手机浏览器打不开没网怎么办 玩多人游戏很紧张怎么办 dnf容易掉线怎么办 qq名字改不了怎么办 手被打火机烧伤怎么办 无效的菜单句柄怎么办 网课被发现刷课怎么办 华硕笔记本玩游戏卡怎么办 手机玩游戏卡顿怎么办? 360n4s玩游戏卡怎么办 手机玩游戏卡死怎么办 游戏占用cpu过高怎么办 h1z1 cpu占用高怎么办 电视盒子网速慢怎么办 gta5解压完然后怎么办 火山遭举报了怎么办 火山被恶意举报怎么办 gta5无网络链接怎么办 pdf格式没有解压密码怎么办 电脑感染蠕虫病毒怎么办 手机积分被盗兑怎么办 自动雨伞卡住了怎么办 全自动伞收不了怎么办 雨伞收不起来怎么办 玩刺激战场卡怎么办 学校电脑网差怎么办 开心斗封号了怎么办 网络不好的地方怎么办