Java如何实现树的同构?
作者:dztom 发布时间:2023-11-28 09:55:19
标签:Java,树,同构
树的同构
备忘!
定义:给定两棵树r1、r2,如果r1可以通过若干次的左子树和右子树互换,使之与r2完全相同,这说明两者同构。
举例
树的构造
树可以由数组或链表来构造:
举例:上图左上角的树通过数组可表示为
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
A | B | C | D | E | G | - | - | - | F | - | H | - |
该方式浪费了部分空间,但适合表示完全二叉树
链表方式则比较直观
除上述两种方式外,还可以采用“类数组”的方式
public static class Node{
String data;
int left;
int right;
}
举例:上图左上角的树可表示为
数组索引 | data | left | right |
---|---|---|---|
0 | A | 1 | 2 |
1 | B | 3 | 4 |
2 | C | 6 | - |
3 | D | - | - |
4 | E | 5 | - |
5 | F | - | - |
6 | G | 7 | - |
7 | H | - | - |
本文的树结构使用了第三种方式
终端输入:
A,1,2
B,3,-
C,-,-
D,-,-
A,2,1
B,3,-
C,-,-
D,-,-
public class TongGou {
private Scanner scanner;
public TongGou(){
scanner = new Scanner(System.in);
}
//树结构
public static class Node{
String data;
int left;
int right;
}
/**
* 创建树
* @param nodes
* @return
*/
public int createTree(Node[] nodes){
int N = nodes.length;
int root = -1;
int[] check = new int[N];
Arrays.fill(check,0); //初始化为0
for (int i=0;i<N;i++){
//输入格式 data,left,right
String next = scanner.next();
String[] inputList = next!=null?next.split(","):null;
if(inputList!=null&&inputList.length==3){
nodes[i] = new Node();
int left = "-".equals(inputList[1])?-1:Integer.parseInt(inputList[1]);
int right = "-".equals(inputList[2])?-1:Integer.parseInt(inputList[2]);
nodes[i].data = inputList[0];
nodes[i].left = left;
nodes[i].right = right;
if(left>0) {
check[left] = 1;
}
if(right>0){
check[right] = 1;
}
}
}
for(int i=0;i<check.length;i++){
if(check[i]==0&&nodes[i].data!=null){
root = i;
break;
}
}
return root;
}
/**
* 判断同构
* @param r1
* @param r2
* @return
*/
public boolean isomorphic(int r1,int r2,Node[] t1,Node[] t2){
//须注意不要漏掉逻辑!
//两个根节点均为null,必同构
if ((r1 == -1) && (r2 == -1)) {
return true;
}
//一个非空 另一个空,必不同构
if(((r1==-1)&&(r2!=-1))||((r1!=-1)&&(r2==-1))){
return false;
}
//两个节点非空 但值不同,必不同构
if(!t1[r1].data.equals(t2[r2].data)){
return false;
}
//两根节点的左孩子为空条件下,则须判断两根节点的右子树是否同构
if(t1[r1].left==-1&&t2[r2].left==-1){
return isomorphic(t1[r1].right,t2[r2].right,t1,t2);
}
//两根节点的左孩子不为空且左孩子的值也相同,须判断两根节点的左子树是否同构以及两根节点的右子树是否同构
//如果左右子树均同构,则整棵树同构
if((t1[r1].left!=-1&&t2[r2].left!=-1)&&(t1[t1[r1].left].data.equals(t2[t2[r2].left].data))){
return isomorphic(t1[r1].left,t2[r2].left,t1,t2)&&isomorphic(t1[r1].right,t2[r2].right,t1,t2);
}else{
//分两种情况解释:
//1、两根节点的左孩子不为空,但左孩子的值不同
//例如:t1[r1.left].data!=t2[r2.left].data。但有t1[r1.left].data==t2[r2.right].data、t1[r1.right].data==t2[r2.left].data
//即有可能r1的左子树与r2的右子树同构、r1的右子树与r2的左子树同构
//故须判断r1的左子树是否与r2的右子树同构,以及r1的右子树是否与r2的左子树同构
//2、两根节点的左孩子一个为空,一个不为空
//例如:r1.left==-1、r2.left!=-1,如果r2.right==-1,显然r1的左子树与r2的右子树同构,此时则有可能r1的右子树与r2的左子树同构
//故须判断r1的左子树是否与r2的右子树同构,以及r1的右子树是否与r2的左子树同构
return isomorphic(t1[r1].left,t2[r2].right,t1,t2)&&isomorphic(t1[r1].right,t2[r2].left,t1,t2);
}
}
public static void main(String[] args) {
TongGou tongGou = new TongGou();
Node[] nodes = new Node[4];
Node[] nodes1 = new Node[4];
int tree1 = tongGou.createTree(nodes);
System.out.println();
int tree2 = tongGou.createTree(nodes1);
boolean isomorphic = tongGou.isomorphic(tree1, tree2, nodes, nodes1);
System.out.println(isomorphic);
}
}
来源:https://blog.csdn.net/dztom/article/details/117910267


猜你喜欢
- 本文实例讲述了C#转换日期类型的方法。分享给大家供大家参考。具体分析如下:如:将日期1999-5-31 11:20转换成 /Date(928
- 1、Idea 设置字体settings --> Editor --> Font2、Idea配置MavenSettings --&
- 使用了Android的系统API实现了多点触控功能,多点触控对设备的硬件有一定的要求,目前市面上的手机几乎都能实现多点触控了。实现多点触控最
- 本文实例讲述了C#实现将程序运行信息写入日志的方法。分享给大家供大家参考。具体如下:1.LogManager类class LogManage
- MyBatisMyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC
- 掌握内存操作流输入和输出都是从文件中来的,当然,也可将输出的位置设置在内存上,这就需要ByteArrayInputStream和ByteAr
- @ConfigurationProperties源码分析@ConfigurationProperties主要作用就是将prefix属性指定的
- 用户列表页面开发项目介绍用户列表页面开发,可以实现简单的查询,删除,修改,和添加用户信息功能。前端使用vue框架,后端使用springboo
- 1. ThreadLocal详解JDK1.2版本起,Java就提供了java.lang.ThreadLocal,ThreadLocal为每个
- 本文介绍的仿IOS对话框的实现,先来看一下效果图具体代码如下:public class AlertDialog { private Cont
- 几个月前写过一篇博客《xUtils3.0框架学习笔记》 ,上面也有记录通过xUtils实现文件上传的使用方法,代码如下:private vo
- springcloud集成nacos遇到的问题1.获取不到配置文件信息有时候新建了配置文件后浏览器访问发现获取不到里面的值,原来spring
- 一、实现效果图关于贝塞尔曲线 二、实现代码1.自定义viewpackage com.czhappy.showintroduce.view;i
- 数字签名广泛用于保护PDF文档,可见数字签名在日常生活中是相当重要的。在这篇文章中我将与大家分享如何给PDF文件添加可见的数字签名。首先我下
- SpringMVC @RequestBody自动转json Http415错误项目中想用@RequestBody直接接收json串转成对象网
- 背景相信很多人都使用过 start.spring.io 来初始化自己的 Spring Boot 工程,这个工具为开发者提供了丰富的可选组件,
- 本文介绍了两种密码加密的方法,这两种很常见可以再百度随意找到。1.摩斯密码;说道密码加密不得不提的方法。很是经典。首先说一下他的对照表,直接
- 前言前面我们已经实现了服务的注册与发现(请戳:SpringCloud系列——Eureka 服务注册与发现),并且在注册中心注册了一个服务my
- 前言以键值对Dictionary<[key], [value]>形式存值,和哈希表很像也是一种无序的结构。要使用Dictiona
- 一、ProgressBar1. 常用类型1.1 不确定式圆形进度条style="@android:style/Widget.Hol