SDUT3340資料結構實驗之二叉樹一:樹的同構
阿新 • • 發佈:2019-01-30
資料結構實驗之二叉樹一:樹的同構
Time Limit: 1000MS Memory limit: 65536K
題目描述
給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。
圖1
圖2
現給定兩棵樹,請你判斷它們是否是同構的。
輸入
輸入資料包含多組,每組資料給出2棵二叉樹的資訊。對於每棵樹,首先在一行中給出一個非負整數N (≤10),即該樹的結點數(此時假設結點從0到N−1編號);隨後N行,第i行對應編號第i注意:題目保證每個結點中儲存的字母是不同的。
輸出
如果兩棵樹是同構的,輸出“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"); } }