给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
图1
图2
现给定两棵树,请你判断它们是否是同构的。
输入格式:
输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。
输出格式:
如果两棵树是同构的,输出“Yes”,否则输出“No”。
输入样例1(对应图1):
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 -
输出样例1:
Yes
输入样例2(对应图2):
8
B 5 7
F - -
A 0 3
C 6 -
H - -
D - -
G 4 -
E 1 -
8
D 6 -
B 5 -
E - -
H - -
C 0 2
G - 3
F - -
A 1 4
输出样例2:
No
1 #include <iostream> 2 #include <cstring> 3 #define MAXSIZE 10 4 using namespace std; 5 //使用静态链表,-1表示null 6 struct TreeNode { 7 char data; 8 int cl; 9 int cr; 10 } t1[MAXSIZE], t2[MAXSIZE]; 11 12 int CreateTree(struct TreeNode t[]) { 13 int N, root; 14 cin >> N; 15 if(!N) return -1; 16 int check[N];//用来标记该结点是否有父节点 17 memset(check, 0, sizeof(check)); 18 for(int i=0; i<N; ++i) { 19 char tcl, tcr; 20 cin >> t[i].data >> tcl >> tcr; 21 if(tcl!='-') { 22 t[i].cl = tcl-'0'; 23 check[t[i].cl] = 1; 24 } 25 else t[i].cl = -1; 26 if(tcr!='-') { 27 t[i].cr = tcr-'0'; 28 check[t[i].cr] = 1; 29 } 30 else t[i].cr = -1; 31 } 32 int index; 33 for(index=0; index<N; index++) { 34 if(!check[index]) break;//没有父结点则为根结点 35 } 36 root = index; 37 return root; 38 } 39 40 bool Isomorphic(int r1, int r2) { 41 /*两棵树存在空的情况*/ 42 //两棵树空,则同构 43 if(r1==-1 && r2==-1) return true; 44 //有一个是-1,才会导致-1,这样就是非同构 45 if(r1*r2 < 0) return false; 46 /*两棵树均不空的情况*/ 47 //根节点数值不相等,非同构 48 if(t1[r1].data != t2[r2].data) return false; 49 //根节点非空且数值相等,则比较t1的左,t2的左和t1的右,t2的右是否同构 50 if(Isomorphic(t1[r1].cl,t2[r2].cl) && Isomorphic(t1[r1].cr,t2[r2].cr)) 51 return true; 52 if(Isomorphic(t1[r1].cl,t2[r2].cr) && Isomorphic(t1[r1].cr,t2[r2].cl)) 53 return true; 54 return false; 55 } 56 57 int main() 58 { 59 int r1, r2; //两个树(两个根) 60 r1 = CreateTree(t1); 61 r2 = CreateTree(t2); 62 if(Isomorphic(r1, r2)) cout << "Yes "; 63 else cout << "No "; 64 return 0; 65 }
注意:cstring头文件的库函数memset()函数原型是extern void *memset(void *buffer, int c, int count) buffer:为指针或是数组,c:是赋给buffer的值,count:是buffer的长度。