Java如何实现树的同构?


Posted in Java/Android onJune 22, 2021

树的同构

备忘!
定义:给定两棵树r1、r2,如果r1可以通过若干次的左子树和右子树互换,使之与r2完全相同,这说明两者同构。

举例

Java如何实现树的同构?

树的构造

树可以由数组或链表来构造:
举例:上图左上角的树通过数组可表示为

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);

    }


}

到此这篇关于Java如何实现树的同构?的文章就介绍到这了,更多相关Java实现树的同构内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Java/Android 相关文章推荐
Spring Data JPA使用JPQL与原生SQL进行查询的操作
Jun 15 Java/Android
Java数据结构之链表相关知识总结
Jun 18 Java/Android
SpringBoot集成Redis,并自定义对象序列化操作
Jun 22 Java/Android
springBoot基于webSocket实现扫码登录
Jun 22 Java/Android
总结一下关于在Java8中使用stream流踩过的一些坑
Jun 24 Java/Android
springboot项目以jar包运行的操作方法
Jun 30 Java/Android
springboot如何接收application/x-www-form-urlencoded类型的请求
Nov 02 Java/Android
spring cloud eureka 服务启动失败的原因分析及解决方法
Mar 17 Java/Android
剑指Offer之Java算法习题精讲二叉树专项训练
Mar 21 Java/Android
详解Flutter和Dart取消Future的三种方法
Apr 07 Java/Android
Java 常见的限流算法详细分析并实现
Apr 07 Java/Android
java版 简单三子棋游戏
May 04 Java/Android
启动Tomcat时出现大量乱码的解决方法
详解java如何集成swagger组件
SpringCloud Alibaba项目实战之nacos-server服务搭建过程
java中重写父类方法加不加@Override详解
Jun 21 #Java/Android
Java并发编程之Executor接口的使用
深入理解以DEBUG方式线程的底层运行原理
浅谈什么是SpringBoot异常处理自动配置的原理
You might like
PHP中的替代语法介绍
2015/01/09 PHP
laravel5.6框架操作数据curd写法(查询构建器)实例分析
2020/01/26 PHP
通过MSXML2自动获取QQ个人头像及在线情况(给初学者)
2007/01/22 Javascript
javascript 写类方式之二
2009/07/05 Javascript
jQuery拖动图片删除示例
2013/05/10 Javascript
JQuery页面地址处理插件jqURL详解
2015/05/03 Javascript
详细分析JavaScript变量类型
2015/07/08 Javascript
jQuery删除节点用法示例(remove方法)
2016/09/08 Javascript
NodeJS 实现手机短信验证模块阿里大于功能
2017/06/19 NodeJs
js移动端图片压缩上传功能
2020/08/18 Javascript
vue项目中jsonp跨域获取qq音乐首页推荐问题
2018/05/30 Javascript
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
[52:14]VG vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python单线程实现多个定时器示例
2014/03/30 Python
跟老齐学Python之使用Python查询更新数据库
2014/11/25 Python
python数据类型_字符串常用操作(详解)
2017/05/30 Python
Python列表list解析操作示例【整数操作、字符操作、矩阵操作】
2017/07/25 Python
Python学习之Django的管理界面代码示例
2018/02/10 Python
Python使用MD5加密算法对字符串进行加密操作示例
2018/03/30 Python
django反向解析URL和URL命名空间的方法
2018/06/05 Python
在IPython中进行Python程序执行时间的测量方法
2018/11/01 Python
提升Python效率之使用循环机制代替递归函数
2019/07/23 Python
Django REST framework 如何实现内置访问频率控制
2019/07/23 Python
python3检查字典传入函数键是否齐全的实例
2020/06/05 Python
Python识别处理照片中的条形码
2020/11/16 Python
K近邻法(KNN)相关知识总结以及如何用python实现
2021/01/28 Python
介绍一下Linux中的链接
2016/06/05 面试题
药剂专业学生求职信范文
2013/12/28 职场文书
建筑节能汇报材料
2014/08/22 职场文书
2014学习优秀共产党员先进事迹材料思想汇报
2014/09/14 职场文书
刑事辩护授权委托书范本
2014/10/17 职场文书
小学班主任经验交流材料
2014/12/16 职场文书
车间主任岗位职责
2015/02/03 职场文书
警示教育片观后感
2015/06/17 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
基于Python实现一个春节倒计时脚本
2022/01/22 Python