資料結構實驗之二叉樹一:樹的同構
老師說的好,一遍不會兩遍,兩遍不會三遍,三遍不會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; }