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

    }

}

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

(0)

相关推荐

  • java之TreeUtils生成一切对象树形结构案例

    项目中经常会遇到各种需要以树形结构展示的功能,比较常见的,如菜单树,分类树,部门树等等,如果为每种类型都遍历递归生成树形结构返回给前端,显得有些冗余且麻烦,并且其实逻辑都是一致的,只是遍历的对象不同而已,故其实可以通过面向接口思维,来实现这种通用工具类的实现. TreeNode用来表示每个树节点的抽象,即需要生成树的对象需要实现此接口. /** * 树节点父类,所有需要使用{@linkplain TreeUtils}工具类形成树形结构等操作的节点都需要实现该接口 * * @param <T>

  • 教你如何使用Java8实现菜单树形数据

    Java8实现菜单树形数据 当我们打开京东商城时,左侧的菜单依次分为三级展示,这是如何实现的呢? 本篇暂不讲述前端,只讲述如何使用java8 的lamada表达式实现树形数据的拼装 1.创建菜单表 CREATE TABLE `pms_category` ( `cat_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类id', `name` char(50) CHARACTER SET utf8 COLLATE utf8_general_ci NU

  • Java二叉树的四种遍历(递归和非递归)

    二叉树的遍历可以分为前序.中序.后序.层次遍历. 前中后是指何时访问中间节点,即前序遍历,遍历节点的顺序为:中->左->右: 中序遍历,遍历节点的顺序为:左->中->右: 后序遍历,遍历节点的顺序为:左->右->中. 前序遍历 递归实现 public void preorder_Traversal(TreeNode root) { if(root==null)return; //访问节点的逻辑代码块 System.out.print(root.val+" &q

  • 利用java实现二叉搜索树

    二叉搜索树的定义 它是一颗二叉树 任一节点的左子树上的所有节点的值一定小于该节点的值 任一节点的右子树上的所有节点的值一定大于该节点的值 特点: 二叉搜索树的中序遍历结果是有序的(升序)! 实现一颗二叉搜索树 实现二叉搜索树,将实现插入,删除,查找三个方面 二叉搜索树的节点是不可以进行修改的,如果修改,则可能会导致搜索树的错误 二叉搜索树的定义类 二叉搜索树的节点类 -- class Node 二叉搜索树的属性:要找到一颗二叉搜索树只需要知道这颗树的根节点. public class BST {

  • Java数据结构学习之树

    一.树 1.1 概念 与线性表表示的一一对应的线性关系不同,树表示的是数据元素之间更为复杂的非线性关系. 直观来看,树是以分支关系定义的层次结构. 树在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可以用树的形象来表示. 简单来说,树表示的是1对多的关系. 定义(逻辑结构): 树(Tree)是n( n>=0 )个结点的有限集合,没有结点的树称为空树,在任意一颗非空树中: 有且仅有一个特定的称为根(root)的结点 . 当n>1的时,其余结点可分为 m( m>0 ) 个互不相交的

  • Java源码解析之平衡二叉树

    一.平衡二叉树的定义 平衡二叉树是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1 .它是一种高度平衡的二叉排序树.意思是说,要么它是一棵空树,要么它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1 .我们将二叉树上结点的左子树深度减去右子树深度的值称为平衡因子BF (Balance Factor),那么平衡二叉树上所有结点的平衡因子只可能是-1 .0 和1. 这里举个栗子: 仔细看图中值为18的节点,18的节点的深度为2 .而它的右子树的深度为0,其差

  • 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{ Stri

  • 带你用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; } 举例:上图左上角的树可表示为 数

  • java数据结构之树基本概念解析及代码示例

    Java中树的存储结构实现 一.树 树与线性表.栈.队列等线性结构不同,树是一...节点与节点之间的父子关系,可以为每个节点增加一个parent域,用以记录该节点的父点 树是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合.它是由n(n>0)个有限节点组成一个具有层次关系的集合.把 它叫做"树"是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的. 树定义和基本术语 定义 树(Tree)是n(n≥0)个结点的有限集T,并且当

  • java JTree JCheckBox树复选框详解

    本文实例为大家分享了java JTree JCheckBox树复选框展示的具体代码,供大家参考,具体内容如下 1.CheckTreeManager.java public class CheckTreeManager extends MouseAdapter implements TreeSelectionListener { private CheckTreeSelectionModel selectionModel = null; // private JTree tree = new JT

  • python树的同构学习笔记

    一.题意理解 给定两棵树T1和T2.如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是"同构的".现给定两棵树,请你判断它们是否是同构的. 输入格式:输入给出2棵二叉树的信息: 先在一行中给出该树的结点树,随后N行 第i行对应编号第i个结点,给出该结点中存储的字母.其左孩子结点的编号.右孩子结点的编号 如果孩子结点为空,则在相应位置给出"-" 如下图所示,有多种表示的方式,我们列出以下两种: 二.求解思路 搜到一篇也是讲这个的,但是那篇并没有完全用到单向

  • 详解Java中字典树(Trie树)的图解与实现

    目录 简介 工作过程 数据结构 初始化 构建字典树 应用 匹配有效单词 关键词提示 总结 简介 Trie又称为前缀树或字典树,是一种有序树,它是一种专门用来处理串匹配的数据结构,用来解决一组字符中快速查找某个字符串的问题.Google搜索的关键字提示功能相信大家都不陌生,我们在输入框中进行搜索的时候,会下拉出一系列候选关键词. 上面这个关键词提示功能,底层最基本的原理就是我们今天说的数据结构:Trie树 我们先看看Tire树长什么样子,以单纯的单词匹配为例,首先它是一棵多叉树结构,根节点是一个空

  • JAVA使用前缀树(Tire树)实现敏感词过滤、词典搜索

    目录 简介 Trie树 code 结论 简介 有时候需要对用户输入的内容进行敏感词过滤,或者实现查找文本中出现的词典中的词,用遍历的方式进行替换或者查找效率非常低,这里提供一个基于Trie树的方式,进行关键词的查找与过滤,在词典比较大的情况下效率非常高. Trie树 Trie树,又叫前缀树,多说无益,直接看图就明白了 词典:[“猪狗”, “小狗”, “小猫”, “小猪”, “垃圾”, “狗东西”] Tire数据结构: code 树节点Node.class /** * trie tree * *

  • java递归菜单树转换成pojo对象

    复制代码 代码如下: package com.cjonline.foundation.authority.pojo;import java.util.ArrayList;import java.util.Collections;import java.util.Iterator;import java.util.List;import org.apache.log4j.Logger;import com.cjonline.foundation.util.CheckNullEmpty;/** *

  • Java实现二分查找树及其相关操作

    二分查找树(Binary Search Tree)的基本操作有搜索.求最大值.求最小值.求前驱.求后继.插入及删除. 对二分查找树的进行基本操作所花费的时间与树的高度成比例.例如有n个节点的完全二叉树,对它进行的基本操作的时间复杂度为O(logn).然而,如果树是一个有n个节点的线性的链,则在这种情况下的时间复杂度为O(n). 1.什么是二分查找树 二分查找树是一种有组织的二叉树.我们可以通过链接节点表示这样一棵树.每个节点包含键(key),数据(data),左子节点(left),右子节点(ri

  • java面试散列表及树所对应容器类及HashMap冲突解决全面分析

    目录 性能分析 HashMap 产生冲突原因及解决方法 HashMap 解决冲突方法 jdk7 与 jdk8 中HashMap的区别 发生冲突 扩容 使用建议 散列表 Hashmap.hashtable.concurrentHashMap.hashset: 树: treemap.treeset.hashset treeset 继承自 treemap,hashset 继承自 hashmap : 性能分析 Map 是 Java 中的接口,Map.Entry 是 Map 的一个内部接口 Map 提供了

随机推荐