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 -
Output
Yes
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct tree//用来存储树的节点 { char data; struct tree *l,*r; }tree; int f[15];//用来标记节点,(未标记过的就是根节点) tree *newtree()//开辟新的节点 { tree *t; t = (tree*)malloc(sizeof(tree)); t->l = t->r = NULL; return t; } struct node { char s; int l,r; }s[15]; tree *creat(int i)//建立二叉树 { if(i==-1) return NULL; tree *t = newtree(); t->data = s[i].s; t->l = creat(s[i].l); t->r = creat(s[i].r); return t; } int judge(tree *t1,tree *t2)//判断是否同构 { if(t1==NULL||t2==NULL) //注意节点为空时要特判 { if(t1==NULL&&t2==NULL)//两个节点全都为空时是相等的 return 1; return 0; } if(t1->data!=t2->data) return 0; if((judge(t1->l,t2->l)&&judge(t1->r,t2->r))||(judge(t1->r,t2->l)&&judge(t1->l,t2->r)))//递归判断节点的(左,左)(右,右)子叶或(左,右)(右,左)子叶是否相同。 return 1; return 0; } int main() { int n,m,i; char a,b,c; tree *t1,*t2; while(scanf("%d",&n)!=EOF) { memset(f,0,sizeof(f)); t1 = newtree(); t2 = newtree(); for(i=0;i<n;i++) { getchar(); scanf("%c %c %c",&a,&b,&c); s[i].s = a; s[i].l = s[i].r = -1; if(b!='-') { s[i].l = b - '0'; f[b-'0'] = 1; } if(c!='-') { s[i].r = c - '0'; f[c-'0'] = 1; } } for(i=0;i<n;i++) if(!f[i]) { t1 = creat(i); break; } scanf("%d",&m); memset(f,0,sizeof(f)); for(i=0;i<m;i++) { getchar(); scanf("%c %c %c",&a,&b,&c); s[i].s = a; s[i].l = s[i].r = -1; if(b!='-') { s[i].l = b - '0'; f[b-'0'] = 1; } if(c!='-') { s[i].r = c - '0'; f[c-'0'] = 1; } } for(i=0;i<m;i++) if(!f[i]) { t2 = creat(i); break; } if(m!=n) printf("No "); else { if(judge(t1,t2)) printf("Yes "); else printf("No "); } } return 0; }