3340資料結構實驗之二叉樹一:樹的同構
阿新 • • 發佈:2019-01-25
N行,第i行對應編號第i個結點,給出該結點中儲存的1個英文大寫字母、其左孩子結點的編號、右孩子結點的編號。如果孩子結點為空,則在相應位置上給出”-”。給出的資料間用一個空格分隔。
注意:題目保證每個結點中儲存的字母是不同的。
資料結構實驗之二叉樹一:樹的同構
Time Limit: 1000ms Memory limit: 65536K 有疑問?點這裡^_^
題目描述
給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。
圖1
圖2
現給定兩棵樹,請你判斷它們是否是同構的。
輸入
輸入資料包含多組,每組資料給出2棵二叉樹的資訊。對於每棵樹,首先在一行中給出一個非負整數N (≤10),即該樹的結點數(此時假設結點從0到N−1編號);隨後注意:題目保證每個結點中儲存的字母是不同的。
輸出
如果兩棵樹是同構的,輸出“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
提示
測試資料對應圖1來源
#include<stdio.h> #include<string.h> #include<stdlib.h> struct node { char data; struct node *lchild,*rchild; }; struct node1 { char data; int a,b; } q[100]; struct node* creat(struct node* root,int n) { root=(struct node*)malloc(sizeof(struct node)); root->lchild=NULL; root->rchild=NULL; root->data=q[n].data; if(q[n].a!=-1) { root->lchild=creat(root->lchild,q[n].a); } if(q[n].b!=-1) { root->rchild=creat(root->rchild,q[n].b); } return root; } int visited[100]; int num=0; int judge(struct node* p,struct node* q) { if(!p&&!q) return 1; else if(p&&q) { if(p->data!=q->data) return 0; else num++; if((judge(p->lchild,q->lchild)&&judge(p->rchild,q->rchild))||(judge(p->rchild,q->lchild)&&judge(p->lchild,q->rchild))) { return 1; } else return 0; } else return 0; } int main() { int n,m; char s1[10],s2[10],s3[10]; while(~scanf("%d",&n)) { memset(visited,0,sizeof(visited)); for(int i=0; i<n; i++) { scanf("%s%s%s",s1,s2,s3); q[i].data=s1[0]; if(s2[0]=='-') q[i].a=-1; else { q[i].a=s2[0]-'0'; visited[q[i].a]=1; } if(s3[0]=='-') q[i].b=-1; else { q[i].b=s3[0]-'0'; visited[q[i].b]=1; } } int flag; struct node *Root; if(n!=0) { int j; for(j=0; j<n; j++) if(!visited[j]) break; Root=creat(Root,j); } scanf("%d",&m); memset(visited,0,sizeof(visited)); for(int i=0; i<m; i++) { scanf("%s%s%s",s1,s2,s3); q[i].data=s1[0]; if(s2[0]=='-') q[i].a=-1; else { q[i].a=s2[0]-'0'; visited[q[i].a]=1; } if(s3[0]=='-') q[i].b=-1; else { q[i].b=s3[0]-'0'; visited[q[i].b]=1; } } int j; for(j=0; j<m; j++) if(!visited[j]) break; struct node *root; root=creat(root,j); num=0; judge(Root,root); if(num==n) printf("Yes\n"); else printf("No\n"); } return 0; }
#include<iostream> using namespace std; struct Tarry { int l,r; char d; } a[12],b[12]; int main() { int n,m; while(cin>>n) { for(int i=0; i<n; i++) { char st1,st2; cin>>a[i].d>>st1>>st2; if(st1=='-') a[i].l=11; else a[i].l=st1-'0'; //轉化為整數 if(st2=='-') //如果為空,這裡指向a[11],因為題目說明最大為9 a[i].r=11; else a[i].r=st2-'0'; } cin>>m; for(int i=0; i<m; i++) { char st1,st2; cin>>b[i].d>>st1>>st2; if(st1=='-') b[i].l=11; else b[i].l=st1-'0'; if(st2=='-') b[i].r=11; else b[i].r=st2-'0'; } int flag=1; //標記變數,預設是同構,若為0,則不同構 if(m!=n) //若兩個樹元素不同,直接判斷不同構 flag=0; else { for(int i=0; i<n; i++) { int tmp=0; //標記變數,預設兩個樹的元素都是不同的,若為1,則有相同的元素 for(int j=0; j<m; j++) { if(a[i].d==b[j].d) { tmp=1; if((a[a[i].l].d==b[b[j].l].d&&a[a[i].r].d==b[b[j].r].d)||(a[a[i].l].d==b[b[j].r].d&&a[a[i].r].d==b[b[j].l].d)) //若相同,檢視它們的左右元素是否相等 break; else { flag=0; break; } } } if(!tmp) flag=0; if(flag==0) break; } } if(!flag) cout<<"No\n"; else cout<<"Yes\n"; } return 0; }