如何判断树的同构?
分情况讨论:
1、两颗树都为空,同构。
2、两棵树有一颗为空,不同构。
3、两棵树都不为空。
(a) 根结点数据不相同
(b) 根结点数据相同。要是r1的左子树与r2的左子树同构&&r1的右子树与r2的右子树同构,或r1的左子树与r2的右子树同构&&r1的右子树与r2的左子树同构,则同构。即:
return (Ismorphic(T1[r1].Left,T2[r2].Right)&&Ismorphic(T1[r1].Right,T2[r2].Left))||(Ismorphic(T1[r1].Left,T2[r2].Left)&&Ismorphic(T1[r1].Right,T2[r2].Right));
总之,先判断完根结点数据相等之外的全部情况,再递归。因为递归的结果总是会回到两个结点的情况上面。
#include <stdio.h>
#define Null -1
typedef int Tree;
struct TNode{
char Data;
Tree Left;
Tree Right;
}T1[10],T2[10];
Tree BuildTree(struct TNode T[])
{
int N,j;
Tree Root=Null;
scanf("%d",&N);
int check[N];
for(int i=0;i<N;i++) check[i]=0;
char cl,cr;
if(N){
for(int i=0;i<N;i++){
scanf("\n%c %c %c",&T[i].Data,&cl,&cr);//不能%c %c %c\n,理由见下文参考
if(cl=='-') T[i].Left=Null;
else{
T[i].Left=cl-'0';
check[T[i].Left]=1;
}
if(cr=='-') T[i].Right=Null;
else{
T[i].Right=cr-'0';
check[T[i].Right]=1;
}
}
for(j=0;j<N;j++) if(check[j]==0) break;
Root=j;
}
return Root;
}
int Ismorphic(Tree r1,Tree r2)
{
if(r1==Null&&r2==Null) return 1;//两颗空树
if(r1==Null&&r2!=Null||r1!=Null&&r2==Null) return 0;//一颗空树一颗非空
//两颗树都非空
if(T1[r1].Data!=T2[r2].Data) return 0;//根结点的数据不相等
//两树根结点非空且相等得到情况
return (Ismorphic(T1[r1].Left,T2[r2].Right)&&Ismorphic(T1[r1].Right,T2[r2].Left))||(Ismorphic(T1[r1].Left,T2[r2].Left)&&Ismorphic(T1[r1].Right,T2[r2].Right));
}
int main()
{
Tree r1,r2;
r1=BuildTree(T1);
r2=BuildTree(T2);
if(Ismorphic(r1,r2))
printf("Yes\n");
else
printf("No\n");
return 0;
}