数据结构--二叉树的创建和遍历
目录
引入
定义
性质
二叉树的创建
迭代法
注意事项:
递归法
注意事项:
二叉树的遍历
深度优先
广度优先
先序遍历(前序遍历)
中序遍历
后序遍历
层序遍历
查找树结构中是否存在某数值
方法一:
方法二:
引入
二叉树(Binary Tree)是数据结构中的一种重要类型。
定义
二叉树是指树中节点的度不大于2的有序树,即每个节点最多有两个子节点,通常被称为左子节点和右子节点。二叉树可以是空树,或者由一个根节点和两棵互不相交的、分别称为左子树和右子树的二叉树组成。
性质
在二叉树的第i层上至多有2^(i-1)个节点(i≥1)。
深度为h的二叉树中至多含有2^h-1个节点(h≥1)。当二叉树为满二叉树时,节点数达到最大值。
若在任意一棵二叉树中,有n0个叶子节点,有n2个度为2的节点,则必有n0=n2+1。
具有n个节点的满二叉树深为log2(n+1)(这里的log是以2为底的对数)。
对于完全二叉树,若其节点按从上至下从左至右的顺序编号,则对于任意节点i:
- 若i=1,则该节点为根节点,无双亲节点。
- 若2i≤n(n为节点总数),则有编号为2i的左节点,否则没有左节点。
- 若2i+1≤n,则有编号为2i+1的右节点,否则没有右节点。
二叉树的创建
如下就是一个二叉树 ,那么如何去构建这么一个二叉树呢?
如上,A、B、C、D......等都是一个节点,要想去构建二叉树,那么就要有额外的类或方法去创建这些节点,在此给出一个 TreeNode类:
public class TreeNode{public int data;public TreeNode left;public TreeNode right;public TreeNode(int data){this.data=data;}//重写toString()方法@Overridepublic String toString(){return "data:"+data+"left:"+left+"right:"+right;}//数据的类型决定数据在内存中的存储形式
}
在这里给出两种方式去构建二叉树:迭代法和递归法。
迭代法
public class BinaryTree {public TreeNode root;public void insert(int data) {//新建一个节点TreeNode newNode = new TreeNode(data);//放入第一个节点if (root == null) {root = newNode;return;}TreeNode currentNode = root;while (true) {if (newNode.data < currentNode.data) {if (currentNode.left != null) {currentNode = currentNode.left;} else {currentNode.left = newNode;return;}} else {if (currentNode.right != null) {currentNode = currentNode.right;} else {currentNode.right = newNode;return;}}}}
}
注意事项:
-
TreeNode类的定义:上述代码中假设已经存在一个名为
TreeNode
的类,它应该包含一个名为data
的整型字段,以及两个名为left
和right
的TreeNode
类型字段(分别表示左子节点和右子节点)。这个类通常还会包含一个构造函数来初始化这些字段。 -
二叉树的性质:上述
insert
方法实现的是一个二叉搜索树(Binary Search Tree, BST)的插入操作。在二叉搜索树中,每个节点的左子树只包含小于节点值的元素,而右子树只包含大于或等于节点值的元素。这种性质使得二叉搜索树在查找、插入和删除操作上具有较高的效率。 -
无限循环的安全性:虽然上述代码中使用了一个无限循环(
while (true)
),但由于在每个条件分支中都有return
语句来终止方法,因此这个循环是安全的。在实际编程中,如果循环条件不是显而易见的,或者循环体中的逻辑比较复杂,那么使用明确的循环条件(如do-while
循环或带有break
语句的while
循环)可能会使代码更加清晰易懂。
递归法
//递归实现树的构建
// 递归插入方法
public void build(int data) {root = insertRec(root, data);
}// 辅助递归函数
private TreeNode insertRec(TreeNode root, int data) {// 如果当前节点为空,创建一个新节点并返回它if (root == null) {root = new TreeNode(data);return root;}// 否则,递归地将数据插入到左子树或右子树中if (data < root.data) {root.left = insertRec(root.left, data);} else {root.right = insertRec(root.right, data);}// 返回(未修改的)当前节点(对于递归调用者很重要)return root;
}
注意事项:
-
递归的基本情况和递归情况:在
insertRec
方法中,基本情况是当当前节点为空时创建一个新节点。递归情况是当当前节点不为空时,根据数据的大小将数据插入到左子树或右子树中。 -
返回当前节点:在递归方法中,返回当前节点(即使它可能没有被修改)是非常重要的。这是因为递归调用需要返回更新后的子树的根节点,以保持树的结构。
-
Java的引用传递:在Java中,对象是通过引用传递的。这意味着当我们将一个对象传递给一个方法时,我们实际上是在传递对象的引用(而不是对象本身)。因此,当我们在
insertRec
方法中修改root.left
或root.right
时,我们实际上是在修改调用者传递的引用所指向的对象。 -
构建二叉搜索树:这段代码实现了一个二叉搜索树的构建过程。在二叉搜索树中,每个节点的左子树只包含小于节点值的元素,而右子树只包含大于或等于节点值的元素。这种性质使得二叉搜索树在查找、插入和删除操作上具有较高的效率。
二叉树的遍历
二叉树的遍历分为深度优先和广度优先两大类。
深度优先
- 先序遍历:按照“根节点-左子树-右子树”的顺序遍历二叉树。
- 中序遍历:按照“左子树-根节点-右子树”的顺序遍历二叉树。在二叉搜索树(BST)中,中序遍历的结果是一个有序序列。
- 后序遍历:按照“左子树-右子树-根节点”的顺序遍历二叉树。
广度优先
- 层序遍历:按照二叉树的层次从上到下、从左到右遍历节点。
接下来实现上述遍历算法:
先序遍历(前序遍历)
//先序遍历
public void beforOrder(TreeNode root){if(root==null){return;}System.out.println(" "+root.data);beforOrder(root.left);beforOrder(root.right);
}
中序遍历
//中序遍历
public void inOrder(TreeNode root){if(root==null){return;}inOrder(root.left);System.out.println(" "+root.data);inOrder(root.right);
}
后序遍历
//后序遍历
public void afterOrder(TreeNode root){if(root==null){return;}afterOrder(root.left);afterOrder(root.right);System.out.println(" "+root.data);
}
层序遍历
//广度优先
public void leveOrder(){LinkedList<TreeNode> queue=new LinkedList<>();queue.add(root);while(!queue.isEmpty()){root=queue.pop();System.out.println(" "+root.data);if(root.left!=null){queue.add(root.left);}if(root.right!=null){queue.add(root.right);}}
}
查找树结构中是否存在某数值
方法一:
//查询是否存在某个数值(true/false)
public boolean isNode(TreeNode root,int data){if(root==null){return false;}if(root.data==data){return true;}return isNode(root.left,data) || isNode(root.right,data);
}
方法二:
// 递归搜索方法
public boolean search(int data) {return searchRec(root, data);
}private boolean searchRec(TreeNode root, int data) {// 如果当前节点为空,说明没有找到目标值if (root == null) {return false;}// 如果当前节点的值等于目标值,返回trueif (root.data == data) {return true;}// 如果目标值小于当前节点的值,递归地在左子树中搜索if (data < root.data) {return searchRec(root.left, data);}else{// 如果目标值大于当前节点的值,递归地在右子树中搜索return searchRec(root.right, data);}}
上述就是二叉树相关操作啦!o(* ̄▽ ̄*)ブ
相关文章:

数据结构--二叉树的创建和遍历
目录 引入 定义 性质 二叉树的创建 迭代法 注意事项: 递归法 注意事项: 二叉树的遍历 深度优先 广度优先 先序遍历(前序遍历) 中序遍历 后序遍历 层序遍历 查找树结构中是否存在某数值 方法一: 方法…...

2024143读书笔记|《遇见》——立在城市的飞尘里,我们是一列忧愁而又快乐的树
2024143读书笔记|《遇见》——立在城市的飞尘里,我们是一列忧愁而又快乐的树 第1章 年年岁岁岁岁年年第2章 遇见第3章 有个叫“时间”的家伙走过第4章 初雪第6章 回首风烟 《华语散文温柔的一支笔:张晓风作品集(共5册)》作者张晓风…...

计算机毕业设计Python+卷积神经网络股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
leetcode hot100【LeetCode 48.旋转图像】java实现
LeetCode 48.旋转图像 题目描述 给定一个 n x n 的二维矩阵 matrix,表示一个图像。请你将该图像顺时针旋转 90 度。 说明: 你必须在 原地 修改输入的二维矩阵。你可以假设矩阵的所有元素将会是整数。 示例 1: 输入: [[1, 2, 3],[4, 5, 6],[7, 8, …...

力扣1382:将二叉搜索树便平衡
给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。如果有多种构造方法,请你返回任意一种。 如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二…...

ElasticSearch学习篇19_《检索技术核心20讲》搜推广系统设计思想
目录 主要是包含搜推广系统的基本模块简单介绍,另有一些流程、设计思想的分析。 搜索引擎 基本模块检索流程 查询分析查询纠错 广告引擎 基于标签倒排索引召回基于向量ANN检索召回打分机制:非精确打分精准深度学习模型打分索引精简:必要的…...
实战ansible-playbook:Ansible Vault加密敏感数据(三)
在实际生产环境中,使用 Ansible Vault 来加密敏感数据是一种常见的做法。以下是一个详细的步骤和实际生产环境的使用案例,展示如何使用 Ansible Vault 来加密和管理敏感数据。 1. 安装 Ansible 确保你已经安装了 Ansible。如果还没有安装,可以使用以下命令进行安装: # 在…...
Python 视频合并工具
Python 视频合并工具 1.简介: 这是一个使用 moviepy 和 tkinter 创建的简单图形用户界面(GUI)应用程序,用于合并两个视频文件,并在两个视频之间添加淡入淡出过渡效果。程序的功能是: 选择两个视频&#…...
JavaScript实用工具lodash库
Lodash中文文档: Lodash 简介 | Lodash中文文档 | Lodash中文网 Lodash是一个功能强大、易于使用的JavaScript实用工具库,它提供了丰富的函数和工具,能够方便地处理集合、字符串、数值、函数等多种数据类型。通过使用Lodash,开发者可以大幅…...
mapstruct DTO转换使用
定义一个基础接口 package com.example.mapstruct;import org.mapstruct.Named;import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Date; import java.util.List;/*** Author zmn Dat…...
Linux(Centos7)---安装nginx(很简单)
安装 sudo yum install nginx -y开机启动与开启服务 sudo systemctl enable nginx sudo systemctl start nginx...
【接口调试】OpenAI ChatGPT API
【接口调试】AbortController 发出请求finish_reason 参数细节 – Openai ChatGPT 文档 发出请求 可以将以下命令粘贴到终端中以运行第一个API请求。 请确保用您的秘密API密钥替换$OPENAI_API_KEY。 curl https://api.openai.com/v1/chat/completions \-H "Content-Ty…...

云轴科技ZStack助力 “上科大智慧校园信创云平台”入选上海市2024年优秀信创解决方案
近日,为激发创新活⼒,促进信创⾏业⾼质量发展,由上海市经济信息化委会同上海市委网信办、上海市密码管理局、上海市国资委等主办的“2024年上海市优秀信创解决方案”征集遴选活动圆满落幕。云轴科技ZStack支持的“上科大智慧校园信创云平台”…...
CPU性能优化-CPU特性
现代CPU持续的添加新特性,使用这些特性可以大大简化找到底层问题的方法。 1 自顶向下微架构分析TMA,是一种识别应用程序低效使用CPU微架构的强大技术,识别负载的瓶颈,定位出现问题的代码具体位置,封装了CPU微架构中复杂…...

Idea使用Maven连接MySQL数据库
1.首先创建Maven文件 2.在pom.xml里添加代码,配置连接MySQL数据库所需要的配置文件。 <dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version&…...
《深入浅出HTTPS》读书笔记(13):块密码算法之迭代模式(续)
CTR模式 每次迭代运算的时候要生成一个密钥流(keystream)。 各个密钥流之间是有关系的,最简单的方式就是密钥流不断递增,所以才叫作计数器模式。 ◎在处理迭代之前,先生成每个密钥流,有n个数据块࿰…...
使用Cmake导入OpenCV库的大坑记录
CMakeLists.txt cmake_minimum_required(VERSION 3.20)set(OpenCV_DIR D:/Package/opencv4/opencv/mingw-build/install) #这里根据自己OpenCV位置设定find_package(OpenCV REQUIRED)project(PROJ1 CXX)add_executable(PROJ1 main.cpp)target_include_directories(PROJ1 PR…...

UE5 打包报错 Unknown structure 的解决方法
在虚幻引擎5.5 打包报错如下: UATHelper: 打包 (Windows): LogInit: Display: LogProperty: Error: FStructProperty::Serialize Loading: Property ‘StructProperty /Game/Components/HitReactionComponent/Blueprints/BI_ReactionInterface.BI_ReactionInterface…...

MySQL之单行函数
目录 1. 函数的理解 单行函数 2. 数值函数 2.1 基本函数 2.2 角度与弧度互换函数 2.3 三角函数 2.4 指数与对数 2.5 进制间的转换 3. 字符串函数 4. 日期和时间函数 4.1 获取日期、时间 4.2 日期与时间戳的转换编辑 4.3 获取月份、星期、星期数、天数等函数 4.4 …...

spring-boot自定义ApplicationListener及源码分析
ApplicationListener是spring boot应用启动时的事件监听器。监听的事件有(包括但不限于): (1)接下来,我们先通过一个例子实现自定义ApplicationListener: 监听器需要实现ApplicationListener<…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...