您的位置:首页 > 理论基础 > 数据结构算法

数据结构实验之二叉树一:树的同构

2016-08-18 17:16 323 查看


数据结构实验之二叉树一:树的同构



Time Limit: 1000MS Memory limit: 65536K


题目描述

给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。



图1



图2

现给定两棵树,请你判断它们是否是同构的。


输入

输入数据包含多组,每组数据给出2棵二叉树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的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

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef struct node
{
char data;
struct node *lchild,*rchild;
} node,*tree;
struct nod
{
char data;  //存节点值
int l,r;  //存左子树和右子树非空的位置
} p[100];
int creat(tree &t,int n);
int tongou(tree t1,tree t2);
int sign[100],num;  //标记此处有孩子
//void PreOrder(tree T);
int main()
{
/*******第一棵树******/
char c,s,r;
int a;
while(cin>>a)
{
memset(sign,0,sizeof(sign));
for(int i=0; i<a; i++)
{

cin>>c>>s>>r;
p[i].data=c;
if(s=='-')
p[i].l=-1;
else
{
p[i].l=s-'0';
sign[p[i].l]=1;
}
if(r=='-')
p[i].r=-1;
else
{
p[i].r=r-'0';//字符转换为子树的位置
sign[p[i].r]=1;
}
}
tree t1;
if(a!=0)
{
int j;
for( j=0; j<a; j++)
{
if(sign[j]!=1)
break;
}
creat(t1,j);
//cout<<j<<endl;
}
//PreOrder(t1);cout<<endl;
/*****第二棵树****/
memset(sign,0,sizeof(sign));
cin>>a;
for(int i=0; i<a; i++)
{

cin>>c>>s>>r;
p[i].data=c;
if(s=='-')
p[i].l=-1;
else
{
p[i].l=s-'0';
sign[p[i].l]=1;
}
if(r=='-')
p[i].r=-1;
else
{
p[i].r=r-'0';//字符转换为子树的位置
sign[p[i].r]=1;
}
}
tree t2;
int j;
for( j=0; j<a; j++)
if(sign[j]!=1)
break;//找到编号位置没有值得地方,第一个缺0,第二个缺3//????
//cout<<j<<endl;
creat(t2,j);

//************************************
//PreOrder(t2);cout<<endl;
/***判同构***/
num=0;
tongou(t1,t2);
if(num==a)
cout<<"Yes\n";
else
cout<<"No\n";
}

}

int creat(tree &t,int n)
{

t=(tree)malloc(sizeof(node));
t->lchild=NULL;
t->rchild=NULL;//必须初始化,这是树的终止,比如 如果没有,遍历输出会无限循环
if(!t) exit(0);
t->data=p
.data;
//cout<<t->data<<endl;
if(p
.l!=-1)
creat(t->lchild,p
.l);
if(p
.r!=-1)
creat(t->rchild,p
.r);

}
int tongou(tree t1,tree t2)
{
if(!t1&&!t2)
return 1;                 //2空树一定同构
else if(t1&&t2)                //再同构需要2树都不为空
{
if(t1->data!=t2->data)       //2节点不同一定不同构
return 0;
else
num++;                //需要每一个都相等
if(tongou(t1->lchild,t2->lchild)&&tongou(t1->rchild,t2->rchild)
||tongou(t1->lchild,t2->rchild)&&tongou(t1->rchild,t2->lchild))
//左子树等于左子树或左子树等于右子树,右子树等于左子树即同构
return 1;
else
return 0;
}
else
return 0;
}
/*void PreOrder(tree T)
{
if(T != NULL)
{
cout<<T->data;
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}测试用的函数*/


[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息