热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

73树的同构(25分)

7-3树的同构(25分)给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵

7-3 树的同构(25 分)


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


图1


图2

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

输入格式:

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

注意:次一个节点并不是根节点,根节点需要自己判断,可以一边建树一边判断,具体的注释在代码中。建树不难,判断那部分较难,很多人可能用的是指针形式

,后面通过指针交换左右子树进行判断,哪种方法极容易错,而且麻烦,可以直接根据是否为空,不为空数值是否相等进行判断下面是C++代码和C语言代码

#include
#include
#include
using namespace std;
#define NULL -1
struct node{char ch;int left;int right;
}tree1[100],tree2[100];
bool book[100];
//建树
int build(struct node tree []){int n;int book[110];char data,l,r;memset(book,0,sizeof(book));//将所有点初始化 scanf("%d",&n);for(int i = 0;i // printf("%c %c %c\n",data,l,r);tree[i].ch = data;//判断左右子树是否存在并标记 if(l == '-'){tree[i].left = NULL;}else{tree[i].left = l-'0';book[l-'0'] = 1;}if(r == '-'){tree[i].right = NULL;}else{tree[i].right = r-'0';book[r-'0'] = 1;}}int root=NULL;//这里一定要赋值为NULL for(int i = 0;i }
bool judge(int root1,int root2){if(root1 ==NULL&& root2==NULL){//判断根节点是否都为空 return true;//都为空则相同 }if(root1==NULL&&root2!=NULL||root1!=NULL&&root2==NULL){return false;//一个根节点为空另外一个不为空则为假 }if(tree1[root1].ch!=tree2[root2].ch){return false;//两棵树根节点都存在,但数值不同则为假 }if(tree1[tree1[root1].left].ch == tree2[tree2[root2].left].ch){//如果左子树的值相等则判断右子树 return judge(tree1[root1].right,tree2[root2].right);}else{//否则判断是否第二棵树是在第一课树左右子树调换之后得到的 return judge(tree1[root1].left,tree2[root2].right)&&judge(tree1[root1].right,tree2[root2].left);}
}
int main(){
// freopen("input.txt","r",stdin);int root1 = build(tree1);int root2 = build(tree2);if(judge(root1,root2)){printf("Yes\n");}else{printf("No\n");}return 0;
}
纯C代码和C++代码思路一样,只是部分语法不同不再解释。

#include
#include
#define NULL -1
struct node{int left,right;char data;
}tree1[100],tree2[100];
int book[1000];
int build(struct node tree[])
{int n,i,root;memset(book,0,sizeof(book));char left,right;scanf("%d",&n);getchar();for(i = 0;i // printf("%c %c %c\n",tree1[i].data,left,right);if(left == '-'){tree[i].left = NULL;}else{tree[i].left = left-'0';book[left-'0'] = 1;}if(right == '-'){tree[i].right = NULL;}else{tree[i].right = right-'0';book[right-'0'] = 1;}}root = NULL;for(i = 0;i }
int judge(int root1,int root2)
{if(root1 == NULL&&root2 == NULL){return 1;}if((root1 == NULL&&root2 != NULL)||(root1 != NULL&&root2 == NULL)){return 0;}if(tree1[root1].data != tree2[root2].data){return 0;}if(tree1[tree1[root1].left].data == tree2[tree2[root2].left].data){return judge(tree1[root1].right,tree2[root2].right);}elsereturn judge(tree1[root1].left,tree2[root2].right) &&judge(tree1[root1].right,tree2[root2].left); }
int main()
{
// freopen("input.txt","r",stdin);int root1,root2,i;root1 = build(tree1);root2 = build(tree2);
// for(i &#61; 0;i <8;i&#43;&#43;)
// {
// printf("%c %d %d\n",tree1[i].data,tree1[i].left,tree1[i].right);
// }
// printf("\n");
// for(i &#61; 0;i <8;i&#43;&#43;)
// {
// printf("%c %d %d\n",tree2[i].data,tree2[i].left,tree2[i].right);
// }if(judge(root1,root2)&#61;&#61;1){printf("Yes\n");}else{printf("No\n");}return 0;
}




推荐阅读
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • 实现一个通讯录系统,可添加、删除、修改、查找、显示、清空、排序通讯录信息
    本文介绍了如何实现一个通讯录系统,该系统可以实现添加、删除、修改、查找、显示、清空、排序通讯录信息的功能。通过定义结构体LINK和PEOPLE来存储通讯录信息,使用相关函数来实现各项功能。详细介绍了每个功能的实现方法。 ... [详细]
author-avatar
手机用户2502906803
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有