题目内容

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

图一

图二

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

输入格式

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

输出格式

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

输入样例(对应图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 -

输出样例

Yes

题目分析

存储问题

首先要解决的是数据的存储问题

1.存储在什么样的数据结构中。

2.如何从给定的输入格式把数据存储进该结构中。

根据题目的条件该二叉树的结点不超过10个,数据量并不大且上限确定,很容易联想到使用结构体数组,即静态链表。

静态链表在物理结构上是一维数组,但其思想与作用与链表相同,用数组下标代替指针指向对应数据位置。这也说明了链表或者说是链式存储是一种物理结构而非逻辑结构。

因此我们可以构造一个结构体。

typedef int treenode;
struct node{
char data;
treenode left;
treenode right;
}T1[MAXSIZE],T2[MAXSIZE];

用整形变量作为数组下标来指向对应位置来代替指针。

关于如何把数据存储进结构中,由于左右子树用'-'和数字一起来表示,所以我使用%c读取左右子树信息后存储在另外变量中并进行了判断,如果是'-'则为Null,否则为对应的数组下标。

根节点问题

由于数组中的节点数据是无序的,所以我们用一个构造一个和结构体数组等长的check数组(与每个结点一一对应)来检查数据是否为任意结点的儿子结点,如果不是则为根节点。

判断方法为每读取一个结点的左右子树,只要不为空,就在对应的check数组中标记。

是否同构问题

在二叉树相关问题中,递归总是被反复提及和使用,因此本问题也可以用递归的方法来解决。

关于一颗二叉树是否同构,我们首先从二叉树的五种基本形态入手:

二叉树的基本形态有:

a)空树;

b)只有根的树,即单结点;

c)有根且有一个左子树;

d)有根且有一个右子树;

e)有根且有一个左子树,有一个右子树。

与下图一一对应

这个知识点看似没有什么用,毕竟一看就知道是那么回事,但是如果加以理解并运用就能很简单的理清思路。

对于两棵二叉树A和B最简单最基本的形态是空树,那么如果两个二叉树都为空树那么必定同构,如果一个不空一个空的话必定不同构。

如果不为空树的话,则看第二种复杂一点的形态,即只有一个根结点的二叉树,如果这两个二叉树的根节点不一致,那么必定不同构。如果一致那么同构(一致同构可以省略因为这种情况包含在下面的情况中)

如果这两颗二叉树更加复杂,有一个子树不为空,那么这时有四种情况。

1.两棵二叉树都是左子树为空,则递归判断两棵二叉树的右子树是否为空。

2.两棵二叉树都是右子树为空,则递归判断两棵二叉树的左子树是否为空。

3.二叉树A左子树为空,二叉树B右子树为空,则递归判断二叉树A的右子树与二叉树B的左子树是否同构。

4.二叉树A右子树为空,二叉树B左子树为空,则递归判断二叉树A的左子树与二叉树B的右子树是否同构。

最复杂的情况,二叉树的左右子树都不为空,首先观察二叉树A和B的左子树元素的数据是否相同,

1.如果相同,则说明这两棵二叉树如果同构的话,必定满足二叉树A左子树与二叉树B左子树同构且二叉树A右子树与二叉树B右子树同构。

2.如果不同,则必须满足二叉树A左子树与二叉树B右子树同构且二叉树A右子树与二叉树B左子树同构才能使整棵二叉树同构。

具体代码如下:

bool isomorphism(treenode root1, treenode root2)
{
if (root1 == Null && root2 == Null)//两棵二叉树都为空树
return true;
if ((root1 != Null && root2 == Null) || (root1 != Null && root2 == Null))//一棵二叉树为空,一棵不为空
return false;
if (T1[root1].data != T2[root2].data)//两棵二叉树根节点数据不同时
return false;
if (T1[root1].left == Null && T2[root2].left == Null)
return isomorphism(T1[root1].right, T2[root2].right);
if(T1[root1].right==Null&&T2[root2].right==Null)
return isomorphism(T1[root1].left, T2[root2].left);
if(T1[root1].left==Null&&T2[root2].right==Null)
return isomorphism(T1[root1].right, T2[root2].left);
if (T1[root1].right == Null && T2[root2].left == Null)
return isomorphism(T1[root1].left, T2[root2].right);//共四种两棵二叉树都有一棵子树为空的情况
if (T1[T1[root1].left].data == T2[T2[root2].left].data)
return (isomorphism(T1[root1].left, T2[root2].left) && isomorphism(T1[root1].right, T2[root2].right));
else
return (isomorphism(T1[root1].left, T2[root2].right) && isomorphism(T1[root1].right, T2[root2].left));//共两种两棵二叉树的左右子树都不为空的情况。
}

完整代码

#include
#include
#define MAXSIZE 10
#define Null -1
typedef int treenode;
struct node{
char data;
treenode left;
treenode right;
}T1[MAXSIZE],T2[MAXSIZE];

treenode createtree(node *tree);
bool isomorphism(treenode root1, treenode root2);

int main(void)
{
int root1, root2;
root1 = createtree(T1);
root2 = createtree(T2);
if (isomorphism(root1, root2))
printf("Yes\n");
else
printf("No\n");
}

treenode createtree(struct node *tree)
{
treenode root = Null;
int check[MAXSIZE] = { 0 };
int size;
char tl, tr;
scanf("%d", &size);
if (size)
{
for (int i = 0; i

提交结果

【PTA】浙江大学数据结构慕课 课后编程作业 03-树1 树的同构的更多相关文章

  1. java数据结构和算法编程作业系列篇-数组

    /** * 编程作业 2.1 向highArray.java程序(清单2.3)的HighArray类添加一个名为getMax()的方法,它返回 数组中最大关键字的值,当数组为空时返回-1.向main( ...

  2. deeplearning.ai 旁听如何做课后编程作业

    在上吴恩达老师的深度学习课程,在coursera上. 我觉得课程绝对值的49刀,但是确实没有额外的钱来上课.而且课程提供了旁听和助学金. 之前在coursera上算法和机器学习都是直接旁听的,这些课旁 ...

  3. 【吴恩达课后编程作业】第二周作业 - Logistic回归-识别猫的图片

    1.问题描述 有209张图片作为训练集,50张图片作为测试集,图片中有的是猫的图片,有的不是.每张图片的像素大小为64*64 吴恩达并没有把原始的图片提供给我们 而是把这两个图片集转换成两个.h5文件 ...

  4. | C语言I作业03

    | C语言I作业03 标签: 18软件 李煦亮 问题 答案 这个作业属于那个课程 C语言程序设计I 这个作业要求在哪里 https://edu.cnblogs.com 我在这个课程的目标是 学会和掌握 ...

  5. Stanford coursera Andrew Ng 机器学习课程编程作业(Exercise 2)及总结

    Exercise 1:Linear Regression---实现一个线性回归 关于如何实现一个线性回归,请参考:http://www.cnblogs.com/hapjin/p/6079012.htm ...

  6. UI-12组结对编程作业总结

    UI-12组结对编程作业总结 源码Github地址 https://github.com/tilmto/TILMTO/tree/master/Arithmetic 作业摘要 本次结对编程作业分为以下两 ...

  7. # 2017-2018-20172309 暑期编程作业:APP

    2017-2018-20172309 暑期编程作业:基于有道词典API的翻译软件的实现. 写在前面:这个博客可以说是拖了很久了.因为做这个APP已经很久了,很多东西都已经忘记了,所以一直都懒得写.但是 ...

  8. ufldl学习笔记与编程作业:Softmax Regression(vectorization加速)

    ufldl学习笔记与编程作业:Softmax Regression(vectorization加速) ufldl出了新教程,感觉比之前的好.从基础讲起.系统清晰,又有编程实践. 在deep learn ...

  9. C语言I—2019秋作业03

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 C语言I-2019秋作业03 我在这个课程的目标是 掌握if-else语句,运算关系 这个作业在那个具体方面帮助我实现目标 row 2 c ...

随机推荐

  1. Python爬虫视频教程

    ├─第1章_[第0周]网络爬虫之前奏 │ ├─第1节_"网络爬虫"课程内容导学 │ │ 第1部分_全课程内容导学.mp4 │ │ 第2部分_全课程内容导学(WS00单元)学习资料. ...

  2. python报错 TypeError: a() got multiple values for argument 'name'

    [问题现象] 在一次调用修饰函数中出现了问题,折腾了一下午,一直报错 TypeError:  got multiple values for argument 只是很简单的调用 from tsu2Ru ...

  3. pycharm---文件名颜色所代表的含义

    绿色,已经加入版本控制暂未提交: 红色,未加入版本控制: 蓝色,加入版本控制,已提交,有改动: 白色,加入版本控制,已提交,无改动: 灰色:版本控制已忽略文件.

  4. GSS系列

    GSS1 直接维护静态区间和即可 #include<bits/stdc++.h> using namespace std; ; int n,a[N]; ]; inline void pus ...

  5. idea实现第一个springboot程序

    1.环境准备 JDK:1.8 Apache Maven: 3.6.1 IntelliJ IDEA 2019.1.3 x64 SpringBoot 1.5.9.RELEASE:1.5.9: 1.1.MA ...

  6. ajax前台数据到后台

    var username = $("#id").val(); var user={"userAccount":username,"userPasswo ...

  7. 提交中文数据乱码问题---web.xml

    前端时间,做了个纯springmvc框架的一个后台系统,遇到了不少问题.特别是编码问题,让我纠结了很久.每次ajax传入数据的时候需要将form中的数据先进行编码 encodeURI(AA); 利用a ...

  8. python 18 re模块

    目录 re 模块 1. 正则表达式 2. 匹配模式 3. 常用方法 re 模块 1. 正则表达式 \w 匹配字母(包含中文)或数字或下划线 \W 匹配非字母(包含中文)或数字或下划线 \s 匹配任意的 ...

  9. POJ 1661 暴力dp

    题意略. 思路: 很有意思的一个题,我采用的是主动更新未知点的方式,也即刷表法来dp. 我们可以把整个路径划分成横向移动和纵向移动,题目一开始就给出了Jimmy的高度,这就是纵向移动的距离. 我们dp ...

  10. C#开发BIMFACE系列7 服务端API之获取文件信息列表

    系列目录     [已更新最新开发文章,点击查看详细] 本文详细介绍如何获取BIMFACE平台中所有上传过的文件信息列表. 请求地址:GET https://file.bimface.com/file ...