二叉树相关算法
1、二叉树基本操作
二叉树的定义就不在这里多说了,下面这个图就是一个简单的二叉树:
二叉树的三种遍历方式:
前序遍历:头左右,也就是先头后左再右:1245367
public static void prePrint(BinaryTreeNode root) {if (root != null) {System.err.print(root.val);prePrint(root.left);prePrint(root.right);}}
中序遍历:左头右,也就是先左后头再右:4251637
public static void midPrint(BinaryTreeNode root) {if (root != null) {midPrint(root.left);System.err.print(root.val);midPrint(root.right);}}
后序遍历:左头右,也就是先左后右再头:4526731
public static void posPrint(BinaryTreeNode root) {if (root != null) {posPrint(root.left);posPrint(root.right);System.err.print(root.val);}}
测试代码:
class BinaryTreeNode {int val;BinaryTreeNode left;BinaryTreeNode right;public BinaryTreeNode(int val) {this.val = val;}public BinaryTreeNode(int val, BinaryTreeNode left, BinaryTreeNode right) {this.val = val;this.left = left;this.right = right;}
}
public static void main(String[] args) {BinaryTreeNode one = new BinaryTreeNode(1,new BinaryTreeNode(2, new BinaryTreeNode(4, null, null), new BinaryTreeNode(5, null, null)),new BinaryTreeNode(3, new BinaryTreeNode(6, null, null), new BinaryTreeNode(7, null, null)));prePrint(one);System.err.println();midPrint(one);System.err.println();posPrint(one);}
那么我们可以看出来,不论是哪种遍历方式,其在处理左右子节点的时候,逻辑都是一样的,都是要递归处理,不同的只是头结点的输出时机,那么可以优化成下面的代码:
public static void print(BinaryTreeNode root, int type) {switch (type) {case 1:if (root != null) {System.err.print(root.val);print(root.left, 1);print(root.right, 1);}break;case 2:if (root != null) {print(root.left, 2);System.err.print(root.val);print(root.right, 2);}break;case 3:if (root != null) {print(root.left, 3);print(root.right, 3);System.err.print(root.val);}break;}}
2、两棵树是否结构一样
如下面的图中,只有左上角和右上角两棵树的结构是一样的,才算符合条件:
Java实现判断两棵树是否一样:
public static boolean isSameTree(BinaryTreeNode node1, BinaryTreeNode node2) {if (node1 == null ^ node2 == null) {return false;}if (node1 == null && node2 == null) {return true;}return node1.val == node2.val && isSameTree(node1.left, node2.left) && isSameTree(node1.right, node2.right);}@Testpublic void testSame() {BinaryTreeNode one = new BinaryTreeNode(1,new BinaryTreeNode(2, new BinaryTreeNode(4, null, null), new BinaryTreeNode(5, null, null)),new BinaryTreeNode(3, new BinaryTreeNode(6, null, null), new BinaryTreeNode(7, null, null)));BinaryTreeNode two = new BinaryTreeNode(1,new BinaryTreeNode(2, new BinaryTreeNode(4, null, null), new BinaryTreeNode(5, null, null)),new BinaryTreeNode(3, new BinaryTreeNode(6, null, null), new BinaryTreeNode(7, null, null)));System.err.println(isSameTree(one, two));}
3、镜面树
镜面树有两种情况:
- 两棵树互为镜面:按照红线对折,可以重叠
- 单棵树两边互为镜面:
代码实现:
public static boolean isMirror(BinaryTreeNode node1, BinaryTreeNode node2) {if (node1 == null ^ node2 == null) {return false;}if (node1 == null && node2 == null) {return true;}return node1.val == node2.val && isMirror(node1.left, node2.right) && isMirror(node1.right, node2.left);}@Testpublic void testMirror() {BinaryTreeNode one = new BinaryTreeNode(1,new BinaryTreeNode(2, new BinaryTreeNode(4, null, null), new BinaryTreeNode(5, null, null)),new BinaryTreeNode(2, new BinaryTreeNode(5, null, null), new BinaryTreeNode(4, null, null)));BinaryTreeNode two = new BinaryTreeNode(1,new BinaryTreeNode(2, new BinaryTreeNode(4, null, null), new BinaryTreeNode(5, null, null)),new BinaryTreeNode(2, new BinaryTreeNode(5, null, null), new BinaryTreeNode(4, null, null)));System.err.println(isMirror(one, two));}
4、树的最大深度
二叉树的最大深度其实就是左子树和右子树的最大深度加一,代码实现如下:
public static int maxDepth(BinaryTreeNode root) {if (root == null) {return 0;}return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;}@Testpublic void testMaxDepth() {BinaryTreeNode two = new BinaryTreeNode(1,new BinaryTreeNode(2, new BinaryTreeNode(4, null, null), new BinaryTreeNode(5, null, null)),new BinaryTreeNode(2, new BinaryTreeNode(5, null, null), new BinaryTreeNode(4, null, null)));System.err.println(maxDepth(two));}
5、还原二叉树
给定一个二叉树的前序遍历数组和中序遍历数组,两个数组中都没有重复值,根据这两个数组还原二叉树,返回头结点
解题思路:仍然是采用递归的方式,几个重要的解题点:
1、前序遍历的第一个元素一定是树的头结点,比如下面这个最基本的二叉树,前序遍历是1,2,3,中序遍历是2,1,3,所以树的头结点一定是1
2、找出中序遍历数组中头结点所在的位置,假设下标为A,那么在前序遍历数组中,从头结点所在下标加1到A(包括两端),以及在中序序遍历数组中从0到A减1(包括两端)的位置都是左子树的节点
比如下面这棵树的头结点是1,在中序遍历数组中的下标是1,那么2就是左子树,再比如文章最前面的第一棵二叉树,前序遍历1245367和中序遍历4251637,根据第二点我们可以得出前序遍历中的245和中序遍历中的425一定是左子树,右子树的逻辑也类似
代码实现:
public static BinaryTreeNode buildTree(int[] preorder, int[] inorder) {// 构建中序遍历数组中元素与索引的映射关系Map<Integer, Integer> inorderMap = new HashMap<>();for (int i = 0; i < inorder.length; i++) {inorderMap.put(inorder[i], i);}return buildTreeHelper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, inorderMap);}private static BinaryTreeNode buildTreeHelper(int[] preorder, int preStart, int preEnd,int[] inorder, int inStart, int inEnd, Map<Integer, Integer> inorderMap) {if (preStart > preEnd || inStart > inEnd) {return null;}int rootVal = preorder[preStart];BinaryTreeNode root = new BinaryTreeNode(rootVal);if (preStart == preEnd) {//相等的时候说明要么是根节点,要么是到了最后一个节点return root;}int rootIndex = inorderMap.get(rootVal);int leftSize = rootIndex - inStart;root.left = buildTreeHelper(preorder, preStart + 1, preStart + leftSize,inorder, inStart, rootIndex - 1, inorderMap);root.right = buildTreeHelper(preorder, preStart + leftSize + 1, preEnd,inorder, rootIndex + 1, inEnd, inorderMap);return root;}@Testpublic void testBuildTree() {int[] preorder = {1, 2, 4, 5, 3, 6, 7};int[] inorder = {4, 2, 5, 1, 6, 3, 7};
// int[] preorder = {1, 2, 3};
// int[] inorder = {2, 1, 3};BinaryTreeNode root = buildTree(preorder, inorder);print(root, 1);System.err.println();print(root, 2);System.err.println();print(root, 3);}
相关文章:

二叉树相关算法
1、二叉树基本操作 二叉树的定义就不在这里多说了,下面这个图就是一个简单的二叉树: 二叉树的三种遍历方式: 前序遍历:头左右,也就是先头后左再右:1245367 public static void prePrint(BinaryTreeNode …...
Vue_Bug npm install报错 code:128
Bug描述: npm install报错 code:128 npm ERR! Warning: Permanently added ‘github.com’ (ED25519) to the list of known hosts. npm ERR! gitgithub.com: Permission denied (publickey). npm ERR! fatal: Could not read from remote repository. n…...

【Unity ShaderGraph】| 如何快速制作一个 马赛克效果 实战
前言 【Unity ShaderGraph】| 如何快速制作一个 马赛克效果 实战一、效果展示二、马赛克效果四、应用实例 前言 本文将使用Unity 的ShaderGraph制作一个马赛克的效果,可以直接拿到项目中使用。对ShaderGraph还不了解的小伙伴可以参考这篇文章:【Unity S…...

【Java 进阶篇】JavaScript DOM Document对象详解
在前端开发中,DOM(文档对象模型)扮演着重要的角色。它允许我们使用JavaScript来与网页文档进行交互,实现动态的网页效果。DOM的核心部分之一就是Document对象,它代表了整个HTML文档。在本篇博客中,我们将深…...
LetCode刷题[简单题](5)按摩师,迭代出最优解(卡尔曼滤波也是类似迭代)
所有的遍历寻求有条件约束的最大值都可以转换成,新的数带来的最大值的变化,问题往这个方向转化就可以,问题都是在最中进行选择的,因此关注的问题最大值得上限就好了,不必关注可能随机的下限。关注随机可能的下限会把问…...

C/C++笔试易错与高频题型图解知识点(二)—— C++部分(持续更新中)
目录 1.构造函数初始化列表 1.1 构造函数初始化列表与函数体内初始化区别 1.2 必须在初始化列表初始化的成员 2 引用&引用与指针的区别 2.1 引用初始化以后不能被改变,指针可以改变所指的对象 2.2 引用和指针的区别 3 构造函数与析构函数系列题 3.1构造函数与析…...

使用new创建动态结构
在运行时创建数组优于在编译时创建数组,对于结构(同一个结构可以存储多种类型的数据。)也是如此。需要在程序运行时为结构分配所需的空间,这也可以使用new运算符来完成。通过使用new,可以创建动态结构。同样࿰…...

论文笔记与复现[156]PARAFAC. tutorial and applications
原文下载:https://www.sciencedirect.com/science/article/abs/pii/S0169743997000324 摘要 本文介绍了PARAFAC的多维分解方法及其在化学计量学中的应用。PARAFAC是PCA向高阶数组的推广,但该方法的一些特性与普通的二维情况截然不同。例如,…...
Python 基础30道测试题
你好,我是悦创。 我会给出 30 道涉及 Python 基础的题目。这些题目将覆盖各种 Python 基础知识点,包括数据类型、控制结构、函数、模块等。 输出 “Hello, World!”。创建一个变量,并为其赋值,然后输出该变量的值。输入两个数&a…...
【环境搭建】linux docker-compose安装rocketmq
创建目录 mkdir -p /data/docker/rocketmq/namesrv/logs mkdir -p /data/docker/rocketmq/broker1/conf mkdir -p /data/docker/rocketmq/broker1/logs mkdir -p /data/docker/rocketmq/broker1/store 给权限 chmod -R 777 /data/docker/rocketmq 创建配置文件 cd /data/d…...

python:使用卷积神经网络(CNN)进行回归预测
作者:CSDN @ _养乐多_ 本文详细记录了从Excel或者csv中读取用于训练卷积神经网络(CNN)模型的数据,包括多个自变量和1个因变量数据,以供卷积神经网络模型的训练。随后,我们将测试数据集应用于该CNN模型,进行回归预测和分析。 该代码进一步修改可用于遥感影像回归模型. …...

数据结构----算法--五大基本算法
数据结构----算法–五大基本算法 一.贪心算法 1.什么是贪心算法 在有多个选择的时候不考虑长远的情况,只考虑眼前的这一步,在眼前这一步选择当前的最好的方案 二.分治法 1.分治的概念 分治法:分而治之 将一个问题拆解成若干个解决方式…...
网格大师如何把b3dm转为osgb格式?
答:在网格大师的倾斜数据处理工具中选中“3DTiles转OSGB”,设定数据输入路径和输出路径提交任务即可。 网格大师是一款能够解决实景三维模型空间参考、原点、瓦块大小不统一,重叠区域处理问题的工具“百宝箱”,集格式转换、坐标转…...

基于深度优先搜索的图遍历
这里写目录标题 基于深度优先搜索的无向图遍历算法流程图Python实现Java实现 基于深度优先搜索的有向图遍历Python实现 基于深度优先搜索的无向图遍历 使用深度优先搜索遍历无向图,将无向图用邻接表存储: 算法流程图 初始化起点 source,当…...

Web3D虚拟人制作简明指南
如何在线创建虚拟人? 虚拟人,也称为数字化身、虚拟助理或虚拟代理,是一种可以通过各种在线平台与用户进行逼真交互的人工智能人。 在线创建虚拟人变得越来越流行,因为它为个人和企业带来了许多好处。 通过虚拟助理或代理,您可以以更具吸引力和个性化的方式与客户或受众进…...
【大数据 - Doris 实践】数据表的基本使用(一):基本概念、创建表
数据表的基本使用(一):基本概念、创建表 1.创建用户和数据库2.Doris 中数据表的基本概念2.1 Row & Column2.2 Partition & Tablet 3.建表实操3.1 建表语法3.2 字段类型3.3 创建表3.3.1 Range Partition3.3.2 List Partition 1.创建用…...

剑指Offer || 038.每日温度
题目 请根据每日 气温 列表 temperatures ,重新生成一个列表,要求其对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。 示例 1: 输入: temperatures…...

URL because the SSL module is not available
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host‘pypi.org’, port443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError(“Can’t connect to HTT PS URL because the…...

excel 日期与时间戳的相互转换
1、日期转时间戳:B1INT((A1-70*365-19)*86400-8*3600)*1000 2、时间戳转日期:A1TEXT((B1/10008*3600)/8640070*36519,"yyyy-mm-dd hh:mm:ss") 以上为精确到毫秒,只精确到秒不需要乘或除1000。 使用以上方法可以进行excel中日期…...
MongoDB中的嵌套List操作
前言 MongoDB区别Mysql的地方,就是MongoDB支持文档嵌套,比如最近业务中就有一个在音频转写结果中进行对话场景,一个音频中对应多轮对话,这些音频数据和对话信息就存储在MongoDB中文档中。集合结构大致如下 {"_id":234…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...