11 是否存在子树 二叉树镜像

2024-05-28 15:48

本文主要是介绍11 是否存在子树 二叉树镜像,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

本博文部分图片, 思路来自于剑指offer 或者编程珠玑

问题描述

这里写图片描述
&
这里写图片描述

思路

对于第一个问题, 判断给定的树[subRoot]是否是给定的树的子树[root]
思路一 : 基于递归, 首先判断给定的两个结点是否为null
     如果两个结点都不为空
        首先判断两个结点的数据是否一致, 如果是 则判断两个子树是否相同, 如果相同 返回true
        否则 递归判断root的左子树中是否存在subRoot匹配的子树, 如果存在 返回true
        否则 递归判断root的右子树中是否存在subRoot匹配的子树, 如果存在 返回true
        如果均没有找到匹配的子树, 返回false
    如果subRoot结点为空 返回true [对于 这两种情况的处理, 只是 我这里是这样处理]
    如果root结点为空 返回false

对于第二个问题, 获取给定树的镜像, 初一看是否是感觉挺神奇的, 书中给出了思路一, 思路二 是使用一个容器来维护需要交换的结点, 进行交换

思路一 : 首先将给定的结点左右子树互换, 然后递归处理左右子树

思路二 : 利用一个容器来维护需要交换的结点, 然后获取容器中的对象, 进行结点的交换

参考代码

/*** file name : Test04isSubTreeExists.java* created at : 8:51:10 PM Jun 6, 2015* created by 970655147*/package com.hx.test05;public class Test04isSubTreeExists {// 1. 判断一棵树中是否含有[存在] 另一颗数的结构// 2. 获取一棵树的镜像public static void main(String []args) {String data = "58 34 12 # # 42 # # 78 68 69 # # # 99 # #";BinTree tree = BinTree.createABinTree(data);String subData = "34 11 # # 42 # #";
//      String subData = "78 68 # # 99 # # #";BinTree subTree = BinTree.createABinTree(subData);boolean isSubTreeExist = isSubTreeExists(tree.root(), subTree.root() );Log.log(isSubTreeExist);getMirrorOfTree(tree.root() );
//      getMirrorOfTree02(tree.root() );Log.log(tree);}// 判断node所在的树  是否存在和subRoot结构一样的子树// 思路 : 如果node节点和subRoot节点都不为空  则比较两个结点的数据, 如果两个结点的数据相同   则判断node中是否存在和subRoot结构一致的子树// 否则  如果node的左子树不为null   递归比较左子树// 否则  如果node的右子树不为null   递归比较右子树// 如果以上三种情况[node结点和subRoot结点数据相同, 递归的左子树, 右子树]任意   一个存在相同的结构, 返回true// 否则如果  subRoot结点为null 返回true// 否则如果  node结点为null    返回false// 不可能到达这里// 否则如果  node结点和subRoot结点均为null  返回truepublic static boolean isSubTreeExists(Node node, Node subRoot) {if(!BinTree.isNodeNull(node) && !BinTree.isNodeNull(subRoot)) {boolean isSubTreeExist = false;if(subRoot.getData().equals(node.getData()) ) {isSubTreeExist = isSubTree(node, subRoot);if(isSubTreeExist) {return true;}} if(!BinTree.isNodeNull(node.getLeft()) ) {isSubTreeExist = isSubTreeExists(node.getLeft(), subRoot );if(isSubTreeExist) {return true;}}if(!BinTree.isNodeNull(node.getRight()) ) {isSubTreeExist = isSubTreeExists(node.getRight(), subRoot );    }return isSubTreeExist;} else if(BinTree.isNodeNull(subRoot)) {return true;} else if(BinTree.isNodeNull(node)) {return false;// can't get there...}else {return true;}}// 获取node结点为根节点的树的镜像   递归实现public static void getMirrorOfTree(Node node) {Node tmp = node.getRight();node.setRight(node.getLeft() );node.setLeft(tmp );if(!BinTree.isNodeNull(node.getLeft()) ) {getMirrorOfTree(node.getLeft() );}if(!BinTree.isNodeNull(node.getRight()) ) {getMirrorOfTree(node.getRight() );}}// 获取node结点为根节点的树的镜像   仿递归实现public static void getMirrorOfTree02(Node node) {Deque<Node> nodes = new LinkedList<Node>();nodes.push(node);while(nodes.size() > 0) {Node top = nodes.pop();Node tmp = top.getRight();top.setRight(top.getLeft() );top.setLeft(tmp );if(!BinTree.isNodeNull(top.getLeft()) ) {nodes.push(top.getLeft() );}if(!BinTree.isNodeNull(top.getRight()) ) {nodes.push(top.getRight() );}}}// 判断node结点是否和subRoot结点结构一致[subRoot结点是node结点所在的树的子集]// 先判断左子树  如果左子树不相同  直接返回false[视为node中不可能存在subRoot的结构 // 在判断右子树  如果左右子树  均相同   则视为存在subRoot的结构   返回trueprivate static boolean isSubTree(Node node, Node subRoot) {boolean isLeftEqual = false, isRightEqual = false;if(!BinTree.isNodeNull(node.getLeft())  && !BinTree.isNodeNull(subRoot.getLeft())  ) {isLeftEqual = node.getLeft().getData().equals(subRoot.getLeft().getData() ) ;if(isLeftEqual) {isLeftEqual = isSubTree(node.getLeft(), subRoot.getLeft() );}} else if(BinTree.isNodeNull(subRoot.getLeft()) ) {isLeftEqual = true;} else if(BinTree.isNodeNull(node.getLeft()) ) {isLeftEqual = false;}if(!isLeftEqual) {return false;}if(!BinTree.isNodeNull(node.getRight()) && !BinTree.isNodeNull(subRoot.getRight())  ) {isRightEqual = node.getRight().getData().equals(subRoot.getRight().getData() );if(isRightEqual) {isRightEqual = isSubTree(node.getRight(), subRoot.getRight() );}} else if(BinTree.isNodeNull(subRoot.getRight()) ) {isRightEqual = true;} else if(BinTree.isNodeNull(node.getRight()) ) {isRightEqual = false;}return (isLeftEqual && isRightEqual);}}

效果截图

这里写图片描述

总结

关于树的算法, 很多东西都涉及到了递归

注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!

这篇关于11 是否存在子树 二叉树镜像的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1011002

相关文章

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Docker镜像pull失败两种解决办法小结

《Docker镜像pull失败两种解决办法小结》有时候我们在拉取Docker镜像的过程中会遇到一些问题,:本文主要介绍Docker镜像pull失败两种解决办法的相关资料,文中通过代码介绍的非常详细... 目录docker 镜像 pull 失败解决办法1DrQwWCocker 镜像 pull 失败解决方法2总

使用国内镜像源优化pip install下载的方法步骤

《使用国内镜像源优化pipinstall下载的方法步骤》在Python开发中,pip是一个不可或缺的工具,用于安装和管理Python包,然而,由于默认的PyPI服务器位于国外,国内用户在安装依赖时可... 目录引言1. 为什么需要国内镜像源?2. 常用的国内镜像源3. 临时使用国内镜像源4. 永久配置国内镜

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

docker如何删除悬空镜像

《docker如何删除悬空镜像》文章介绍了如何使用Docker命令删除悬空镜像,以提高服务器空间利用率,通过使用dockerimage命令结合filter和awk工具,可以过滤出没有Tag的镜像,并将... 目录docChina编程ker删除悬空镜像前言悬空镜像docker官方提供的方式自定义方式总结docker

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

查询Oracle数据库表是否被锁的实现方式

《查询Oracle数据库表是否被锁的实现方式》本文介绍了查询Oracle数据库表是否被锁的方法,包括查询锁表的会话、人员信息,根据object_id查询表名,以及根据会话ID查询和停止本地进程,同时,... 目录查询oracle数据库表是否被锁1、查询锁表的会话、人员等信息2、根据 object_id查询被

shell脚本快速检查192.168.1网段ip是否在用的方法

《shell脚本快速检查192.168.1网段ip是否在用的方法》该Shell脚本通过并发ping命令检查192.168.1网段中哪些IP地址正在使用,脚本定义了网络段、超时时间和并行扫描数量,并使用... 目录脚本:检查 192.168.1 网段 IP 是否在用脚本说明使用方法示例输出优化建议总结检查 1