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

相关文章

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Conda国内镜像源及配置过程

《Conda国内镜像源及配置过程》文章介绍Conda镜像源使用方法,涵盖临时指定单个/多个源、永久配置及恢复默认设置,同时说明main(官方稳定)、free(逐渐弃用)、conda-forge(社区更... 目录一、Conda国内镜像源二、Conda临时使用镜像源指定单个源临时指定多个源创建环境时临时指定源

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

Python如何判断字符串中是否包含特殊字符并替换

《Python如何判断字符串中是否包含特殊字符并替换》这篇文章主要为大家详细介绍了如何使用Python实现判断字符串中是否包含特殊字符并使用空字符串替换掉,文中的示例代码讲解详细,感兴趣的小伙伴可以了... 目录python判断字符串中是否包含特殊字符方法一:使用正则表达式方法二:手动检查特定字符Pytho

Docker安装MySQL镜像的详细步骤(适合新手小白)

《Docker安装MySQL镜像的详细步骤(适合新手小白)》本文详细介绍了如何在Ubuntu环境下使用Docker安装MySQL5.7版本,包括从官网拉取镜像、配置MySQL容器、设置权限及内网部署,... 目录前言安装1.访问docker镜像仓库官网2.找到对应的版本,复制右侧的命令即可3.查看镜像4.启