题目地址

https://pta.patest.cn/pta/test/15/exam/4/question/711

5-3 树的同构   (25分)

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

图1

图2

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

输入格式:

输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数NN (\le 10≤10),即该树的结点数(此时假设结点从0到N-1N−1编号);随后NN行,第ii行对应编号第ii个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。

输出格式:

如果两棵树是同构的,输出“Yes”,否则输出“No”。

输入样例1(对应图1):

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 -

输出样例1:

Yes

输入样例2(对应图2):

8
B 5 7
F - -
A 0 3
C 6 -
H - -
D - -
G 4 -
E 1 -
8
D 6 -
B 5 -
E - -
H - -
C 0 2
G - 3
F - -
A 1 4

输出样例2:

No

/*
评测结果
时间 结果 得分 题目 编译器 用时(ms) 内存(MB) 用户
2017-07-08 15:57 答案正确 25 5-3 gcc 14 1
测试点结果
测试点 结果 得分/满分 用时(ms) 内存(MB)
测试点1 答案正确 7/7 14 1
测试点2 答案正确 7/7 2 1
测试点3 答案正确 3/3 2 1
测试点4 答案正确 2/2 1 1
测试点5 答案正确 3/3 2 1
测试点6 答案正确 3/3 10 1
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 10 /*
思路
跟视频教程中的从根向下遍历来判断同构不同,本算法从叶子节点向上搜索。
因为树是静态建立的,所以父节点比较容易记录。
*/
struct treenode{//创建节点结构体
int data; //存放内容
int father; //存放父节点位置
int lc; //左儿子
int rc; //右儿子
int isleaf; //是否为叶节点
}; typedef struct tree{//树结构体
struct treenode nodes[MAXLEN];//节点单元
int len;//节点数量
int root;//根节点位置
}* ptrTree; ptrTree CreateTree()//建树
{
int i;
ptrTree T;
T=(ptrTree)malloc(sizeof(struct tree));
for(i=0;i<MAXLEN;i++)
T->nodes[i].father=-1; //提前将每个节点的父节点都初始化为-1
return T;
} void DestoryTree(ptrTree T) //释放空间
{
free(T);
} void input(ptrTree T) //读入树
{
int i,length;
scanf("%d",&length);
// printf("%d,line40\n",length);//test
T->len=length;
getchar();//skip a space
for(i=0;i<length;i++)
{
T->nodes[i].data=getchar();
getchar();//skip a space
T->nodes[i].lc=getchar();
getchar();//skip a space
T->nodes[i].rc=getchar();
getchar();//skip a space T->nodes[i].lc-='0';
T->nodes[i].rc-='0'; // printf("line58\n");//test
// printf("#%d data=%c L=%d R=%d Father=%d leaf=%d\n",i,T->nodes[i].data,T->nodes[i].lc,T->nodes[i].rc,T->nodes[i].father,T->nodes[i].isleaf);//test if(T->nodes[i].lc>=0)//如果一个节点有孩子,将此节点标记为孩子的父节点
T->nodes[T->nodes[i].lc].father=i;
if(T->nodes[i].rc>=0)
T->nodes[T->nodes[i].rc].father=i;
if(T->nodes[i].lc<0 && T->nodes[i].rc<0)//如果一个节点没有孩子,那么此节点为叶节点
T->nodes[i].isleaf=1; // printf("#%d data=%c L=%d R=%d Father=%d leaf=%d\n",i,T->nodes[i].data,T->nodes[i].lc,T->nodes[i].rc,T->nodes[i].father,T->nodes[i].isleaf);//test
} for(i=0;i<length;i++){//遍历整棵树,父节点为-1的节点即为根。不过次算法后来也没用上这个量,留着不删了。
if(T->nodes[i].father<0){
T->root=i;
break;
}
}
}
void printTree(ptrTree T)//测试用函数,输出树,看是否正确
{
int i;
printf("Tree.len=%d root=%d\n ",T->len,T->root);
for(i=0;i<T->len;i++){
printf("#%d %c L=%d R=%d Father=%d leaf=%d\n",i,T->nodes[i].data,T->nodes[i].lc,T->nodes[i].rc,T->nodes[i].father,T->nodes[i].isleaf);
}
} int CheckPath(ptrTree T1,ptrTree T2,int idx,int otheridx)//测试以下标idx的节点为起点,搜索另一棵树上的data相同的节点,若这二者的父节点值也相同,那么递归搜索到根为止。如不相同,则返回0;
{
int i,t1f,t2f;
t1f=T1->nodes[idx].father;
if(otheridx<0){//T2对应的下标值如果已知,那么不用再搜一遍了
for(i=0;i<T1->len;i++)
if(T1->nodes[idx].data==T2->nodes[i].data)
break;
t2f=T2->nodes[i].father;
}else
t2f=T2->nodes[otheridx].father; if(( t1f<0 && t2f>=0) || (t1f>=0 && t2f<0)) return 0;
if (T1->nodes[t1f].data==T2->nodes[t2f].data){
if(T1->nodes[t1f].father<0)
return 1;
else return CheckPath(T1,T2,t1f,t2f);
}
else return 0; }
int Judge(ptrTree T1,ptrTree T2)
{
int i,flag=1;
if(T1->len!=T2->len)//两棵树若节点数不同直接跳出
return 0; if(T1->len==0){//两棵树都是空树,那么肯定算同构
return 1;
}
if(T1->len==1){//若两棵树都只有一个节点,那么比较节点的值是否相同即可
if(T1->nodes[0].data==T2->nodes[0].data)
return 1;
else return 0;
}
for(i=0;i<T1->len;i++){
if(T1->nodes[i].isleaf==1) {//搜寻所有的叶子节点,搜索向上的路径。如果两棵树所有叶子节点的向上路径都相同,那么这两棵树同构
flag=CheckPath(T1,T2,i,-1);//因为不知道第二棵树对应该叶子的index,所以填-1让它自己搜
if(flag==0) return 0;
}
}
return 1;//循环期间没出过差错,那么可以return 1了
}
int main()
{
int i;
ptrTree T1,T2;
T1=CreateTree();
T2=CreateTree();
input(T1);
input(T2);
// printTree(T1);//test
// printTree(T2);//test
i=Judge(T1,T2);
if(i==1) printf("Yes");
else printf("No");
}

  

PTA 03-树1 树的同构 (25分)的更多相关文章

  1. PTA 树的同构 (25分)

    PTA 树的同构 (25分) 输入格式: 输入给出2棵二叉树树的信息.对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号):随后N行,第i行对应编号第 ...

  2. PTA 11-散列1 电话聊天狂人 (25分)

    题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/722 5-14 电话聊天狂人   (25分) 给定大量手机用户通话记录,找出其中通话次数 ...

  3. PTA 09-排序2 Insert or Merge (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/675 5-13 Insert or Merge   (25分) According to ...

  4. PTA 08-图8 How Long Does It Take (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/674 5-12 How Long Does It Take   (25分) Given ...

  5. PTA 02-线性结构4 Pop Sequence (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/665 5-3 Pop Sequence   (25分) Given a stack wh ...

  6. (数学) PTA 1005 继续(3n+1)猜想 (25 分)

    1005 继续(3n+1)猜想 (25 分) 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程 ...

  7. PAT 03-树1 树的同构 (25分)

    给定两棵树T1和T2.如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是"同构"的.例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A.B.G的左右孩子互换后 ...

  8. PTA 06-图2 Saving James Bond - Easy Version (25分)

    This time let us consider the situation in the movie "Live and Let Die" in which James Bon ...

  9. PTA 5-12 How Long Does It Take (25分)

    这题看不太懂题目啊~  参考的http://blog.csdn.net/qq_26437925/article/details/49420089?locationNum=6&fps=1 先放着 ...

随机推荐

  1. list的一些功能

    x = [1,5,2,3,4] 1.列表反转序: 函数法: x.reverse()该方法没有返回值但会对列表进行反向排序. 注意 不能y=x.reverse(),会得到None 如果要的话要y=rev ...

  2. Spark MLlib编程API入门系列之特征提取之主成分分析(PCA)

    不多说,直接上干货! 主成分分析(Principal Component Analysis,PCA), 将多个变量通过线性变换以选出较少个数重要变量的一种多元统计分析方法. 参考 http://blo ...

  3. 里特定律 - Little's Law

    里特定律(Little's Law)源自排队理论,是IT系统性能建模中最广为人知的定律. 里特定律揭示了前置时间(Lead Time).在制品数量(Work In Progress, WIP)和吞吐率 ...

  4. Selenium私房菜系列1 -- Selenium简介

    一.Selenium是什么? Selenium是ThroughtWorks公司一个强大的开源Web功能测试工具系列,本系列现在主要包括以下4款: 1.Selenium Core:支持DHTML的测试案 ...

  5. 生成hprof文件,用MAT进行分析

    生成hprof文件可以在DDMS选中进程点击窗口左上角的"dump hprof file"按钮来直接生成,也可以通过在程序加代码中来生成 代码2: void generateHpr ...

  6. 计数器:counter

    组成:2属性,1方法 属性1: counter-reset 命名 属性2: counter-increment 启动/自增 方法 : counter()/counters() 调用方法 1.计数器 命 ...

  7. 微信小程序开发系列教程三:微信小程序的调试方法

    微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 这个教程的前两篇文章,介绍了如何用下图所示的微信开发者工具自动生成一个Hel ...

  8. SQLite -创建表

    SQLite -创建表 SQLite CREATE TABLE语句用于创建一个新表在任何给定的数据库.创建一个基本表包括表命名和定义其列,每列的数据类型 语法: CREATE TABLE语句的基本语法 ...

  9. 联玛客(W 笔试)

    纸质算法题 1. 输入数据:1.3.2.4.8... 输出数据:3.1.4.2.8... 找出规律,写出一个程序求解,并附上时间复杂度和空间复杂度 我的答案: 规律一:奇偶位互换 假设输入数据长度为5 ...

  10. slides 在线ppt && React && Angular

    现在主流前端框架 有3个 Vue React Angular 如果有时间就都学习,理解一下他们的差异性~ 在线ppt的一个网站 这个是npm讲解的,不错 https://slides.com/seld ...