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




推荐阅读
  • 本文探讨了如何在 F# Interactive (FSI) 中通过 AddPrinter 和 AddPrintTransformer 方法自定义类型(尤其是集合类型)的输出格式,提供了详细的指南和示例代码。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 本文深入探讨了 Delphi 中类对象成员的核心概念,包括 System 单元的基础知识、TObject 类的定义及其方法、TClass 的作用以及对象的消息处理机制。文章不仅解释了这些概念的基本原理,还提供了丰富的补充和专业解答,帮助读者全面理解 Delphi 的面向对象编程。 ... [详细]
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
  • 在进行QT交叉编译时,可能会遇到与目标架构不匹配的宏定义问题。例如,当为ARM或MIPS架构编译时,需要确保使用正确的宏(如QT_ARCH_ARM或QT_ARCH_MIPS),而不是默认的QT_ARCH_I386。本文将详细介绍如何正确配置编译环境以避免此类错误。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 主板IO用W83627THG,用VC如何取得CPU温度,系统温度,CPU风扇转速,VBat的电压. ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • CentOS 6.8 上安装 Oracle 10.2.0.1 的常见问题及解决方案
    本文记录了在 CentOS 6.8 系统上安装 Oracle 10.2.0.1 数据库时遇到的问题及解决方法,包括依赖库缺失、操作系统版本不兼容、用户权限不足等问题。 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • 序列化与反序列化是数据处理中的重要技术,特别是在网络通信和数据存储中。它们允许将复杂的数据结构转换为可传输或存储的格式,再从这些格式恢复原始数据。本文探讨了序列化与反序列化的基本概念,以及它们在不同协议模型中的角色。 ... [详细]
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社区 版权所有