zoukankan      html  css  js  c++  java
  • 同构树

    什么是同构树:

    给定两颗树T1和T2,如果T1可以通过若干次左右孩子交换变成T2,我们就称两棵树是同构的。

    将整个过程拆分来看一下,增加一些二叉树的操作:

    首先是二叉树的建立:

    struct tnode{
        char data;
        int right,left;
    };
    void buildtree(tnode t[])
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>t[i].data>>t[i].left>>t[i].right;    
    }

    找二叉树的根节点:(就在刚才的代码中修改,其实很简单)

    int buildtree(tnode t[])
    {
        int n,root=-1,f[N];
        memset(f,0,sizeof(f));
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>t[i].data>>t[i].left>>t[i].right;   
            if(t[i].left>0) f[t[i].left]=1;
            if(t[i].right>0) f[t[i].right]=1;
        }
        for(int i=1;i<=n;i++)
            if(!f[i])
            {
                root=i;break;
            }
        return root;     
    }

    对二叉树的遍历:

    先序遍历:(其实在这个基础上稍微更改一下就可以实现中序和后序遍历)

    void  preord(int root,tnode t[]){
        if(root!=-1){
            cout<<root<<t[root].data<<" ";//这三个更改顺序就可以了
            preord(t[root].left,t);
            preord(t[root].right,t);
        }
    }

    层次遍历(利用队列):

    void levelt(int root,tnode t[]){
        queue<int> q;
        q.push(root);
        while(!q.empty()){
            int r=q.front();q.pop();cout<<r<<t[r].data<<" ";
            if(t[r].left!=-1)    q.push(t[r].left);
            if(t[r].right!=-1) q.push(t[r].right);
        } 
    }

    判断同构:

    基本思路:1、如果两颗树均为空,认为同构;2、如果均不为空且值相等,则去递归判断左右子树是否相等或者T1左子树等于T2右子树&&T1右子树等于T2左子树;其余都为不同构

    判断同构:

    int issame(int r1,int r2){
        if(r1==-1&&r2==-1) return 1;
        if((r1!=-1&&r2!=-1)&&(t1[r1].data==t2[r2].data)){
            int one=issame(t1[r1].left,t2[r2].left)&&issame(t1[r1].right,t2[r2].right);
            int two=issame(t1[r1].left,t2[r2].right)&&issame(t1[r1].right,t2[r2].left);
            return (one||two);
        }
        else return 0;    
    }

    例题:

    输入:

    8
    A 1 2
    B 3 4
    C 5 -
    D - -
    E 6 -
    G 7 -
    F - -
    H - -
    8
    G - 4
    B 7 6
    F - -
    A 5 1
    H - -
    C 0 -
    D - -
    E 2 -

    判断这两颗树是否为同构树,完整代码(稍微注意下输入):

    #include <bits/stdc++.h>
    using namespace std;
    const int N=205;
    struct tnode{
        char data;
        int right,left;
    };
    tnode t1[N],t2[N];
    int buildtree(tnode t[]){//建树 
        int n,root=-1,f[N];
        char cl,cr;
        
        //cout<<f[0]<<endl;
        cin>>n;
        for(int i=0;i<n;i++) f[i]=-1;
        for(int i=0;i<n;i++){
            cin>>t[i].data>>cl>>cr;
            if(cl=='-') t[i].left=-1;
            else{
                int tmp=cl-'0';
                f[tmp]=1;t[i].left=tmp;
                
            }    
            if(cr=='-') t[i].right=-1;
            else{
                int tmp=cr-'0';
                f[tmp]=1;t[i].right=tmp;
            }    
        }
        for(int i=0;i<n;i++)
        {
            if(f[i]==-1){
                root=i;break;
            }
        }
            
        return root;
    }
    void  preord(int root,tnode t[]){
        if(root!=-1){
            cout<<root<<t[root].data<<" ";
            preord(t[root].left,t);
            preord(t[root].right,t);
        }
    }
    void levelt(int root,tnode t[]){
        queue<int> q;
        q.push(root);
        while(!q.empty()){
            int r=q.front();q.pop();cout<<r<<t[r].data<<" ";
            if(t[r].left!=-1)    q.push(t[r].left);
            if(t[r].right!=-1) q.push(t[r].right);
        } 
    }
    int issame(int r1,int r2){
        if(r1==-1&&r2==-1) return 1;
        if((r1!=-1&&r2!=-1)&&(t1[r1].data==t2[r2].data)){
            int one=issame(t1[r1].left,t2[r2].left)&&issame(t1[r1].right,t2[r2].right);
            int two=issame(t1[r1].left,t2[r2].right)&&issame(t1[r1].right,t2[r2].left);
            return (one||two);
        }
        else return 0;    
    }
    int main(){
        int r1=buildtree(t1);
        int r2=buildtree(t2);
        if(issame(r1,r2)) cout<<"yes";
        else cout<<"no"; 
        /*
        preord(r1,t1);//前序遍历
        cout<<endl;
        levelt(r1,t1);//层次遍历 
        */
    }
    View Code

     快读版输入:

    #include <bits/stdc++.h>
    using namespace std;
    const int N=205;
    struct tnode{
        char data;
        int right,left;
    };
    tnode t1[N],t2[N];
    int read()
    {
        int x=0;char z=getchar();
        while(!(z=='-'||z>='0'&&z<='9'))z=getchar();
        if(z=='-') return -1;
        if(z=='-') return -1;
        while(z>='0'&&z<='9')
            x=(x<<3)+(x<<1)+z-'0',z=getchar();
        return x;
    }
    int buildtree(tnode t[]){//建树 
        int n,root=-1,f[N];
        char cl,cr;
        
        //cout<<f[0]<<endl;
        //cin>>n;
        n=read();
        for(int i=0;i<n;i++) f[i]=-1;
        for(int i=0;i<n;i++){
            //cin>>t[i].data>>cl>>cr;
            scanf("
    %c",&t[i].data);
            t[i].left=read();
            if(t[i].left!=-1) f[t[i].left]=1;
            t[i].right=read();
            if(t[i].right!=-1) f[t[i].right]=1;
        }
            /*
            if(cl=='-') t[i].left=-1;
            else{
                int tmp=cl-'0';
                f[tmp]=1;t[i].left=tmp;
                
            }    
            if(cr=='-') t[i].right=-1;
            else{
                int tmp=cr-'0';
                f[tmp]=1;t[i].right=tmp;
            }    
        }
        */
        for(int i=0;i<n;i++)
        {
            if(f[i]==-1){
                root=i;break;
            }
        }
        return root;
    }
    void  preord(int root,tnode t[]){
        if(root!=-1){
            cout<<root<<t[root].data<<" ";
            preord(t[root].left,t);
            preord(t[root].right,t);
        }
    }
    void levelt(int root,tnode t[]){
        queue<int> q;
        q.push(root);
        while(!q.empty()){
            int r=q.front();q.pop();cout<<r<<t[r].data<<" ";
            if(t[r].left!=-1)    q.push(t[r].left);
            if(t[r].right!=-1) q.push(t[r].right);
        } 
    }
    int issame(int r1,int r2){
        if(r1==-1&&r2==-1) return 1;
        if((r1!=-1&&r2!=-1)&&(t1[r1].data==t2[r2].data)){
            int one=issame(t1[r1].left,t2[r2].left)&&issame(t1[r1].right,t2[r2].right);
            int two=issame(t1[r1].left,t2[r2].right)&&issame(t1[r1].right,t2[r2].left);
            return (one||two);
        }
        else return 0;
        
    }
    int main(){
        int r1=buildtree(t1);
        int r2=buildtree(t2);
        if(issame(r1,r2)) cout<<"yes";
        else cout<<"no"; 
        //preord(r1,t1);//前序遍历
        //cout<<endl;
        //levelt(r1,t1);//层次遍历 
    }
    View Code
  • 相关阅读:
    冒泡排序与选择排序
    SVN-cheanup反复操作失败的问题。
    js区分汉字和字符,校验长度
    maven的安装与使用
    java获取登陆用户的IP地址
    kafka创建topics 错误: 找不到或无法加载主类 FilesJavajdk1.7.0_80lib;C:Program
    SOAPwebservice 与Restfull webservice之间的区别
    CAD数据导入Arcgis10.1的依赖关系
    wpf之StackPanel、WrapPanel、WrapPanel之间的关系
    浅谈修饰符
  • 原文地址:https://www.cnblogs.com/sunny99/p/12623096.html
Copyright © 2011-2022 走看看