首先这里说明一下这里同构是指:两课树可以通过有限次变换左右子树变为同一棵树,举例如下
上图所示的两棵树就是同构的,其他的我们都没变化,这里我们就举上图的例子,先看同构函数
//判断两棵树是否同构
int Isomorphic(Ptree t1,Ptree t2){
if((t1==NULL)&&(t2==NULL))return 1;//都为空
if(((t1==NULL)&&(t2!=NULL))||((t1!=NULL)&&(t2==NULL))) return 0;//一个为空另一个不为空
if(t1->data!=t2->data) return 0;//根节点的值不一样
if((t1->lchild==NULL)&&(t2->lchild==NULL)) return Isomorphic(t1->lchild,t2->rchild);
if(((t1->lchild!=NULL)&&(t2->lchild!=NULL))&&(t1->lchild->data==t2->lchild->data))//没有交换
return (Isomorphic(t1->lchild,t2->lchild)&&Isomorphic(t1->rchild,t2->rchild));//如果两个都不为空且左儿子相等,应该递归的找左对应左,右对应右
else
return (Isomorphic(t1->lchild,t2->rchild)&&Isomorphic(t1->rchild,t2->lchild));//否则就是交换了,递归的判断左对应右,右对应左
};
上面的函数全面地考虑到了所有的情况,因此没毛病
上面两棵树的输入分别应该是ABD##E##CGH####和
ACG#H###BE##D##
运行的结果如下图
下面附上完整代码
#include "stdio.h"
#include "stdlib.h"
typedef struct tree
{
char data;
struct tree *lchild;
struct tree *rchild;
}*Ptree;
//树的建立
Ptree createTree();
//先序遍历
void preOrder(Ptree t);
//中序遍历
void intOrder(Ptree t);
//后序遍历
void postOrder(Ptree t);
//判断两棵树是否同构
int Isomorphic(Ptree t1,Ptree t2);
void main()
{
Ptree t1;
printf("先序创建二叉树T1,用空格代表虚结点:\n");
t1=createTree();
printf("前序遍历:");
preOrder(t1) ;
printf("\n");
printf("中序遍历:");
intOrder(t1);
printf("\n");
printf("后序遍历:");
postOrder(t1);
printf("\n");
printf("\n");
fflush(stdin);//这句话是一定要有的。。不然t2无法正确输入
Ptree t2;
printf("先序创建二叉树T2,用空格代表虚结点:\n");
t2=createTree();
printf("前序遍历:");
preOrder(t2) ;
printf("\n");
printf("中序遍历:");
intOrder(t2);
printf("\n");
printf("后序遍历:");
postOrder(t2);
printf("\n");
printf("\n");
int n= Isomorphic(t1,t2);
printf("%d\n",n);
system("pause");
}
Ptree createTree() //树的建立
{
char ch;
Ptree t;
scanf("%c",&ch);//输入二叉树数据
if(ch==' ') //判断二叉树是否为空
t=NULL;
else
{
t=(Ptree)malloc(sizeof(Ptree)); //二叉树的生成
t->data=ch;
t->lchild=createTree();
t->rchild=createTree();
}
return t;
}
void preOrder(Ptree t) //先序遍历
{
if(t)
{
printf("%c",t->data);
preOrder(t->lchild);
preOrder(t->rchild);
}
}
void intOrder(Ptree t) //中序遍历
{
if(t)
{
intOrder(t->lchild);
printf("%c",t->data);
intOrder(t->rchild);
}
}
void postOrder(Ptree t) //后序遍历
{
if(t)
{
postOrder(t->lchild);
postOrder(t->rchild);
printf("%c",t->data);
}
}
//判断两棵树是否同构
int Isomorphic(Ptree t1,Ptree t2){
if((t1==NULL)&&(t2==NULL))return 1;//都为空
if(((t1==NULL)&&(t2!=NULL))||((t1!=NULL)&&(t2==NULL))) return 0;//一个为空另一个不为空
if(t1->data!=t2->data) return 0;//根节点的值不一样
if((t1->lchild==NULL)&&(t2->lchild==NULL)) return Isomorphic(t1->lchild,t2->rchild);
if(((t1->lchild!=NULL)&&(t2->lchild!=NULL))&&(t1->lchild->data==t2->lchild->data))//没有交换
return (Isomorphic(t1->lchild,t2->lchild)&&Isomorphic(t1->rchild,t2->rchild));//如果两个都不为空且左儿子相等,应该递归的找左对应左,右对应右
else
return (Isomorphic(t1->lchild,t2->rchild)&&Isomorphic(t1->rchild,t2->lchild));//否则就是交换了,递归的判断左对应右,右对应左
};
完成