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

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

老師說的好,一遍不會兩遍,兩遍不會三遍,三遍不會n遍。。。。總有會的那一天,只要你敢付出學會的時間。。

                                                                                                                                                                             ---------劉老師

Problem Description

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

 

圖1

圖2

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

Input

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

Output

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

Sample Input

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 -

Sample Output

Yes

Hint

測試資料對應圖1

Source

xam

程式碼:

#include <iostream> #include <bits/stdc++.h> using namespace std; struct node {     char data;     int l;     int r; } tree1[15],tree2[15]; int judge(int i,int j)///子節點一樣的情況有兩種,一種是 左左右右,一種是 左右右左。。。 {     if(tree1[tree1[i].l].data==tree2[tree2[j].l].data&&tree1[tree1[i].r].data==tree2[tree2[j].r].data)         return 1;     if(tree1[tree1[i].l].data==tree2[tree2[j].r].data&&tree1[tree1[i].r].data==tree2[tree2[j].l].data)         return 1;     return 0; } int main() {     int n,m;     int i,j;     char a,b,c;     while(~scanf("%d",&n))     {         for(i=0; i<n; i++)         {             getchar();             scanf("%c %c %c",&a,&b,&c);             tree1[i].data = a;             if(b!='-')                 tree1[i].l = b-'0';             else tree1[i].l = -1;             if(c!='-')                 tree1[i].r = c-'0';             else tree1[i].r = -1;         }         scanf("%d",&m);         for(i=0; i<m; i++)         {             getchar();             scanf("%c %c %c",&a,&b,&c);             tree2[i].data = a;             if(b!='-')                 tree2[i].l = b-'0';             else tree2[i].l = -1;             if(c!='-')             tree2[i].r = c-'0';             else tree2[i].r = -1;         }         if(n!=m)         {             printf("No\n");             continue;         }         int f = 1;         for(i=0; i<n; i++)///用陣列儲存樹的結點時,儘量不要用遞迴。。。         {             for(j=0; j<m; j++)///這種方式可以很好的解決。             {                 if(tree1[i].data==tree2[j].data)///找到父親結點相同。                 {                     if(judge(i,j))///看子節點是否也一樣。                     {                         break;                     }                 }             }             if(j==m)             {                 f = 0;                 break;             }         }         if(!f)             printf("No\n");         else printf("Yes\n");     }     return 0; }