您的位置:首页 > 其它

如何判断一个二叉树是否为另一个二叉树的子树

2017-07-31 19:57 405 查看
1. 递归的方式

/*

struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}

};*/

class Solution {

public:

    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)

    {

         //递归的实现方式

        bool result=false;

        if(pRoot1==NULL||pRoot2==NULL)

            return false;

        if(pRoot1->val==pRoot2->val)

            result=getResult(pRoot1,pRoot2);//这里的递归是进入下面的函数!!!

        if(result==false)

            result=HasSubtree(pRoot1->left,pRoot2);//这里的递归是递归自己!!!

        if(result==false)

            result=HasSubtree(pRoot1->right,pRoot2);//这里的递归是递归自己!!!

        return result;

    }

    bool getResult(TreeNode* p1,TreeNode* p2){

        if(p1==NULL&&p2==NULL)

            return true;

        if(p1==NULL&&p2!=NULL)

            return false;

        if(p1!=NULL&&p2==NULL)

            return true;

        if(p1->val==p2->val)

            return getResult(p1->left,p2->left)&&getResult(p1->right,p2->right);

        else

            return false;

    }

};

递归的过程如上面所示,需要注意的是这是两个不同的递归过程!!!!

2. 序列化然后利用KMP算法进行模式串的匹配

KMP算法的时间复杂度为O(m+n),可以用均摊分析来证明。具体的证明可以查看http://www.matrix67.com/blog/archives/115。

普通的模式串匹配算法的时间复杂度为o(m*n)

/*

struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}

};*/

class Solution {

public:

    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)

       

    {

         if(pRoot1==NULL||pRoot2==NULL)

            return false;

         //先将两棵树进行序列化,然后进行模式串匹配!!!

        string s1,s2;

        getResult(pRoot1,s1);

        getResult(pRoot2,s2);

        //下面是KMP

        return getkmp(s1,s2);

    }

    void getResult(TreeNode* r,string& s){

        //采用先序遍历的过程,需要注意的是这里不需要#,只需要!!!!原因是如果带有#,那么对于s2来说,s1中包含的s2也许他的孩子并不是空,但是s2中叶节点的孩子

        //为空,这样会导致结果的错误!!!因为生成的字符串必然是不相等的,所以不需要#。

        if(r!=NULL)

            s=s+to_string(r->val)+"!";

        else{

            return;

        }

        getResult(r->left,s);

        getResult(r->right,s);

        return;  

    }

    bool getkmp(string s1,string s2){

        int* next=getnext(s2);

        int j = 0;

        int size=s1.length();

        int size2=s2.length();

        for (int i = 0; i < size; i++) {  

          while (j
aca4
> 0 && s1[i] !=s2[j])  

                j = next[j];  

        if (s1[i] ==s2[j])  

            j++;  

        if (j == size2) {  

            return true;    

        }  

        }

        return false;

    }

    //求s1的next数组

   int* getnext(string b){

       int len=b.length();  

       int j=0;  

          

       int* next=new int[len+1];//next表示长度为i的字符串前缀和后缀的最长公共部分,从1开始  

       next[0]=next[1]=0;  

          

       for(int i=1;i<len;i++)//i表示字符串的下标,从0开始  

       {//j在每次循环开始都表示next[i]的值,同时也表示需要比较的下一个位置  

          while(j>0&&b[i]!=b[j])j=next[j];  

          if(b[i]==b[j])j++;  

             next[i+1]=j;  

       }      

       return next;  

    }

};

字符串匹配算法除了KMP之外还有BM等。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: