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

相关文章

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

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

python 字典d[k]中key不存在的解决方案

《python字典d[k]中key不存在的解决方案》本文主要介绍了在Python中处理字典键不存在时获取默认值的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录defaultdict:处理找不到的键的一个选择特殊方法__missing__有时候为了方便起见,

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal

【408DS算法题】039进阶-判断图中路径是否存在

Index 题目分析实现总结 题目 对于给定的图G,设计函数实现判断G中是否含有从start结点到stop结点的路径。 分析实现 对于图的路径的存在性判断,有两种做法:(本文的实现均基于邻接矩阵存储方式的图) 1.图的BFS BFS的思路相对比较直观——从起始结点出发进行层次遍历,遍历过程中遇到结点i就表示存在路径start->i,故只需判断每个结点i是否就是stop

linux 判断某个命令是否安装

linux 判断某个命令是否安装 if ! [ -x "$(command -v git)" ]; thenecho 'Error: git is not installed.' >&2exit 1fi

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

OpenStack镜像制作系列5—Linux镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作