热门标签 | 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;
}




推荐阅读
  • 编译原理中的语法分析方法探讨
    本文探讨了在编译原理课程中遇到的复杂文法问题,特别是当使用SLR(1)文法时遇到的多重规约与移进冲突。文章讨论了可能的解决策略,包括递归下降解析、运算符优先级解析等,并提供了相关示例。 ... [详细]
  • c语言二元插值,二维线性插值c语言
    c语言二元插值,二维线性插值c语言 ... [详细]
  • Hanks博士是一位著名的生物技术专家,他的儿子Hankson对数学有着浓厚的兴趣。最近,Hankson遇到了一个有趣的数学问题,涉及求解特定条件下的正整数x,而不使用传统的辗转相除法。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 本文通过C++语言实现了一个递归算法,用于解析并计算数学表达式的值。该算法能够处理加法、减法、乘法和除法操作。 ... [详细]
  • 线段树详解与实现
    本文详细介绍了线段树的基本概念及其在编程竞赛中的应用,并提供了一个具体的线段树实现代码示例。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • 本文介绍如何手动实现一个字符串连接函数,该函数不依赖于C语言的标准字符串处理函数,如strcpy或strcat。函数原型为void concatenate(char *dest, char *src),其主要作用是将源字符串src追加到目标字符串dest的末尾。 ... [详细]
  • 实现系统调用
    实现系统调用一、实验环境​本次操作还是基于上次编译Linux0.11内核的实验环境进行操作。环境如下:二、实验目标​通过对上述实验原理的认识,相信 ... [详细]
  • 本文提供了一个使用C语言实现的顺序表区间元素删除功能的完整代码示例。该程序首先初始化一个顺序表,然后根据用户输入的数据进行插入操作,最后根据指定的区间范围删除相应的元素,并输出最终的顺序表。 ... [详细]
  • 深入浅出C语言指针
    指针是C语言中极其重要的数据类型,广泛应用于各种数据结构的表示、数组和字符串的操作以及内存地址的处理。本文将通过实例详细解析指针的基本概念及其应用。 ... [详细]
  • 网络流24题——试题库问题
    题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
  • Android与JUnit集成测试实践
    本文探讨了如何在Android项目中集成JUnit进行单元测试,并详细介绍了修改AndroidManifest.xml文件以支持测试的方法。 ... [详细]
  • 在开发iOS应用时,面对不同状态(如数据加载成功、无数据、未登录、网络异常等)的界面管理,如何实现既高效又美观的用户体验?本文探讨了几种最佳实践方法。 ... [详细]
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社区 版权所有