1. 程式人生 > >SDUT3340資料結構實驗之二叉樹一:樹的同構

SDUT3340資料結構實驗之二叉樹一:樹的同構

資料結構實驗之二叉樹一:樹的同構

Time Limit: 1000MS Memory limit: 65536K

題目描述

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。




圖1


圖2

現給定兩棵樹,請你判斷它們是否是同構的。

輸入

 輸入資料包含多組,每組資料給出2棵二叉樹的資訊。對於每棵樹,首先在一行中給出一個非負整數N (10),即該樹的結點數(此時假設結點從0N−1編號);隨後N行,第i行對應編號第i
個結點,給出該結點中儲存的1個英文大寫字母、其左孩子結點的編號、右孩子結點的編號。如果孩子結點為空,則在相應位置上給出”-”。給出的資料間用一個空格分隔。
注意:題目保證每個結點中儲存的字母是不同的。

輸出

 如果兩棵樹是同構的,輸出“Yes”,否則輸出“No”。

示例輸入

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 -

示例輸出

Yes
 #include <stdio.h>
 #include <string.h>
 #define MaxTree 10
 #define Null -1
 typedef char ElemType;
 typedef int Tree;
 typedef struct BiTree
 {
     ElemType data;
     Tree lchild;
     Tree rchild;
 }BiTree;
 BiTree T1[MaxTree],T2[MaxTree];
 Tree CBT(BiTree T[],int N)
 {
     if(N==0) return Null;

     char e[2],lc[2],rc[2];
     int check[N];//記錄是否被指向;
     memset(check,0,sizeof(check));
     for(int i=0;i<N;i++)
     {//資料輸入;
      //記錄指向關係;
         scanf("%s %s %s",e,lc,rc);
         T[i].data=e[0];
         //左子樹;
         if(lc[0]!='-')
         {
             T[i].lchild=lc[0]-'0';
             check[T[i].lchild]=1;
         }
         else
             T[i].lchild=Null;
         //右子樹;
         if(rc[0]!='-')
         {
             T[i].rchild=rc[0]-'0';
             check[T[i].rchild]=1;
         }
         else
             T[i].rchild=Null;
     }
     for(int j=0;j<N;j++)//遍歷尋根;
         if(!check[j])
            return j;
 }
 int is(Tree R1,Tree R2)
 {
     if(R1==Null&&R2==Null)//兩顆空樹同構;
        return 1;
     if((R1==Null&&R2!=Null)||(R1!=Null&&R2==Null))//有且僅有一棵空樹,不同構;
        return 0;
     if(T1[R1].data!=T2[R2].data)//根的元素不相同,不同構;
        return 0;
     if(T1[R1].lchild==Null&&T2[R2].lchild==Null)//兩棵樹的左子樹均為空樹,判斷兩棵樹的右子樹;
        return is(T1[R1].rchild,T2[R2].rchild);
     if(T1[R1].lchild!=Null//T1左子樹不為空
        &&T2[R2].lchild!=Null//T2右子樹不為空
        &&T1[T1[R1].lchild].data==T2[T2[R2].lchild].data)//T1和T2的左子樹根元素相同
        return (is(T1[R1].lchild,T2[R2].lchild)&&is(T1[R1].rchild,T2[R2].rchild));
     return (is(T1[R1].lchild,T2[R2].rchild)&&is(T1[R1].rchild,T2[R2].lchild));
 }
int main()
{
    int n,m;
    Tree R1,R2;
    while(~scanf("%d",&n))
    {
        R1=CBT(T1,n);
        scanf("%d",&m);
        R2=CBT(T2,m);
        if(is(R1,R2))
            printf("Yes\n");
        else
            printf("No\n");
    }
}