数据结构奇妙旅程之二叉平衡树

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
系列专栏:xiaoxie的JAVA系列专栏——CSDN博客●'ᴗ'σσணღ*
我的目标:"团团等我💪( ◡̀_◡́ ҂)" 

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​+关注(互三必回)!

一.二叉平衡树

1.二叉平衡树的概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

它的左右子树也分别为二叉搜索树

从上述概念以及图中可以看出,二叉搜索树具有以下特性:

1. 二叉搜索树中最左侧的节点是树中最小的节点,最右侧节点一定是树中最大的节点

2. 采用中序遍历遍历二叉搜索树,可以得到一个有序的序列 

2.二叉搜索树的主要操作

1. 查询

2.插入

1.插入的为一颗空树

直接插入即可

2.. 如果树不是空树,按照查找逻辑确定插入位置,插入新结点

根据二叉搜索树的性质插入节点,"左小右大"

  1. 对于树中的任意节点 n,其左子树中的所有节点的值都小于 n 的值,其右子树中的所有节点的值都大于 n 的值。
  2. 在插入新节点时,需要按照二叉搜索树的性质找到合适的位置插入,保持树的有序性。
  3. 插入节点后,需要调整树的结构,保证树仍然是一个二叉搜索树。

3.删除

假设删除节点cur那么cur有以下几种情况

1.cur 的左孩子为空,右孩子不为空,

2.cur 的右孩子为空,左孩子不为空.

3.cur 的左右孩子均为空.

4.cur 的左右孩子均不为空.

接下来博主将会通过画图的形式来演示这四种情况该如何删除节点

1.cur 的左孩子为空,右孩子不为空

 2.cur 的右孩子为空,左孩子不为空.

3. cur 的左右孩子均为空.

4. cur 的左右孩子均不为空.

1.假设我们需要删除节点70,我们首先需要通过遍历二叉搜索树,找到70这个节点的对应位置.

2.我们发现70这个节点,左右孩子均不为空,这个时候就不可以通过简单的删除就可以了,我们需要用到替换法,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被 删除节点中,再来处理该结点的删除问题.

2.1这里解释一下为什么是在它的右子树中寻找中序下的第一个结点(关键码最小),当需要删除一个节点时,如果该节点有右子树,则可以在右子树中找到中序遍历下的第一个节点(即右子树中最小的节点)来替代当前节点。这是因为右子树中的所有节点都大于当前节点,而右子树中最小的节点又小于右子树中的所有其他节点,所以用右子树中的最小节点来替代当前节点可以保持二叉搜索树的性质不变。

3.找到"替罪羊"节点 t 后我们就需要把要删除的节点cur使他的值等于t .

4.最后删除节点t即可.

4.二叉搜索树基本操作的Java代码实现

public class BinarySearchTree {public static class TreeNode {public TreeNode left;public TreeNode right;public int val;public TreeNode(int val) {this.val = val;}}public TreeNode root;/*** 查询节点是否存在* @author xiaoxie* @date 2024/3/6 10:44* @param val* @return boolean*/public boolean search(int val) {if(root == null) {System.out.println();return false;}TreeNode cur = root;while (cur != null) {if(val < cur.val) {cur = cur.left;} else if (val > cur.val) {cur = cur.right;}else {System.out.println("找到了");return true;}}System.out.println("该节点"+val+"不存在");return false;}/*** 插入节点* @author xiaoxie* @date 2024/3/6 10:47* @param val*/public void insertTreeNode(int val) {TreeNode node = new TreeNode(val);if(root == null) {root = node;return;}TreeNode parent = null;TreeNode cur = root;while (cur != null) {if(node.val < cur.val) {parent = cur;cur = cur.left;} else if (node.val > cur.val) {parent = cur;cur = cur.right;}else {System.out.println("节点值 " + val + " 已经存在于树中,不进行插入操作");return;}}//cur = nullif(node.val < parent.val) {parent.left = node;}else {parent.right = node;}}/*** 删除节点* 可以使用替罪羊的方法来实现* @author xiaoxie* @date 2024/3/6 12:15* @param val* @return boolean*/public boolean remove(int val) {//首先先找到是哪一个节点if(root == null) {return false;}TreeNode parent = null;TreeNode cur = root;while (cur != null) {if(cur.val > val) {parent = cur;cur = cur.left;} else if (cur.val < val) {parent = cur;cur = cur.right;}else {break;}}//cur == null 说明要删除的节点不在二叉搜索树上if(cur == null) {return false;}// cur有多种情况//1.cur 没有左右孩子//2.cur 只有左孩子//3.cur 只有右孩子//4.cur 有左右孩子 -- 需要使用替罪羊的方法来删除if(cur.right != null && cur.left != null) {TreeNode t = cur.right;TreeNode tp = cur;while (t.left != null) {tp = t;t = t.left;}cur.val = t.val;//使要删除的节点的值等于替罪羊节点//删除替罪羊节点if(tp.left == t) {tp.left = t.right;}else {//出现tp.right = t 的情况,t节点一开始就是叶子节点tp.right = t.right;}}else {//cur 只有右孩子if(cur.left == null && cur.right != null){if(parent == null) {root = cur.right;}else {if(parent.val < cur.val) {parent.right = cur.right;}else {parent.left = cur.right;}}}//cur 只有左孩子else if (cur.left != null && cur.right == null) {if(parent == null) {root = cur.left;}else {if(parent.val < cur.val) {parent.right = cur.left;}else {parent.left = cur.left;}}}//cur 没有左右孩子else  {if(parent == null) {root = null;}else {if(parent.val < cur.val) {parent.right = null;}else {parent.left = null;}}}}return true;}

 5.性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。 对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度 的函数,即结点越深,则比较次数越多。 但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:

1.最优情况下,二叉搜索树为完全二叉树

其平均比较次数为:log N;

2.最差情况下,二叉搜索树退化为单支树

 其平均比较次数为: 2 / N

问题:如果退化成单支树,二叉搜索树的性能就失去了。那能否进行改进,不论按照什么次序插入关键码,都可以 是二叉搜索树的性能最佳?

那就需要用到AVL树了通过旋转来使二叉搜索树变成完全二叉树的形式,这里博主就不过多的赘述了,如果感兴趣,可以为博主点上一个关注,在下一篇文章中,博主将详细解读AVL树

感谢你的阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/734408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图神经网络实战(4)——基于Node2Vec改进嵌入质量

图神经网络实战&#xff08;4&#xff09;——基于Node2Vec改进嵌入质量 0. 前言1. Node2Vec 架构1.2 定义邻居1.2 在随机游走中引入偏向性1.3 实现有偏随机游走 2. 实现 Node2Vec小结系列链接 0. 前言 Node2Vec 是一种基于 DeepWalk 的架构&#xff0c;DeepWalk 主要由随机游…

qt 格式化打印 日志 QMessagePattern 格式词法语法及设置

一、qt源码格式化日志 关键内部类 QMessagePattern qt为 格式化打印日志 提供了一个简易的 pattern(模式/格式) 词法解析的简易的内部类QMessagePattern,作用是获取和解析自定义的日志格式信息。 该类在qt的专门精心日志操作的源码文件Src\qtbase\src\corelib\global\qloggi…

[LeetCode][226]翻转二叉树

题目 226. 翻转二叉树 给你一棵二叉树的根节点 root&#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#x…

深度学习500问——Chapter02:机器学习基础(5)

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 2.14 贝叶斯分类器 2.14.1 图解极大似然估计 极大似然估计的原理&#xff0c;用一张图片来说明&#xff0c;如下图所示&#xff1a; 例&#xff1a;有两个外形完全相同的箱子&#xff0c;1号箱…

重学SpringBoot3-内容协商机制

重学SpringBoot3-内容协商机制 ContentNegotiationConfigurer接口配置内容协商URL参数Accept头使用Url扩展名 自定义内容协商格式步骤1: 注册自定义媒体类型步骤2: 实现HttpMessageConverter接口步骤3: 使用自定义HttpMessageConverter 注意点 在 Spring Boot 3 中&#xff0c;…

vue学习笔记21-组件传递数据_Props

组件与组件之间不是完全独立的&#xff0c;而是有交集的&#xff0c;那就是组件与组件之间是可以传递数据的 传递数据的解决方案就是props 父级&#xff1a; 在父级中引入子集 <template><h3>Parent</h3><Child/> </template><script> i…

GFP-GAN环境搭建推理测试

引子 近期&#xff0c;文生图&#xff0c;wav2lip很火&#xff0c;文生图&#xff0c;见识的太多&#xff0c;不多说了。wav2lip其通过语音驱动唇部动作并对视频质量进行修复&#xff0c;里面一般涉及到三个步骤&#xff0c;文本到语音转化&#xff0c;语音驱动唇部动作&#…

【C++初阶】第五站:C/C++内存管理 (匹配使用,干货到位)

前言&#xff1a; 本文知识点&#xff1a; 1. C/C内存分布2. C语言中动态内存管理方式3. C中动态内存管理4. operator new与operator delete函数 5. new和delete的实现原理 &#xff08;干货在此&#xff09; 6. 定位new表达式(placement-new)7. 常见面试题 目录 C/C内…

Java反射、枚举类和lambda表达式

前言&#xff1a; 本章我们就来了解Java中的反射和枚举类。枚举类和反射其实有些关系&#xff0c;接下来我们就来学习他们的使用。 反射&#xff1a; 反射的作用&#xff1a; 反射&#xff1a;反射允许对成员变量&#xff0c;成员方法和构造方法的信息进行编程访问。 Java中有…

CVE-2021-31440:eBPF verifier __reg_combine_64_into_32 边界更新错误

文章目录 前言漏洞分析构造 vuln reg 漏洞利用漏洞修复参考 前言 影响版本&#xff1a;Linux 5.7 ~ 5.11.20 8.8 编译选项&#xff1a;CONFIG_BPF_SYSCALL&#xff0c;config 所有带 BPF 字样的编译选项。General setup —> Choose SLAB allocator (SLUB (Unqueued Allocat…

从0到1手把手实现RPC|01 RpcProvider本地实现

RPC的简化版原理如下图&#xff08;核心是代理机制&#xff09;。 1.本地代理存根: Stub2.本地序列化反序列化3.网络通信4.远程序列化反序列化5.远程服务存根: Skeleton6.调用实际业务服务7.原路返回服务结果8.返回给本地调用方 注意处理异常。 RpcProvider的本地实现 1、工…

xss.haozi.me靶机 通关

0x00 没有任何过滤可以直接注入<img srcx οnerrοralert(1)> 0x01 使用了testarea标签将我们的输入内容以普通的字符串进行展示 但是我们可以将标签进行闭合 </textarea><img srcx οnerrοralert(1)> 0x02 我们依然可以先闭合之后添加属性a" οncl…

Java17 --- SpringCloud之Consul

目录 一、consul的使用 1.1、主要功能 1.2、安装及运行 1.3、添加微服务到consul 1.3.1、8001微服务添加相关pom、配置文件、注解 1.3.2、80微服务添加相关pom、配置文件、注解 1.4、三个注册中心异同 1.5、consul进行分布式配置 1.5.1、修改8001的yml配置文件 1.5.2…

数字化运营在教育行业的技术架构实践总结

随着科技的不断进步和数字化时代的到来&#xff0c;教育行业也正面临着数字化转型的挑战和机遇。教育行业的数字化运营需要依靠合理的技术架构来支撑&#xff0c;本文将探讨教育行业数字化运营的技术架构设计。 ## 第一步&#xff1a;需求分析和架构设计 在构建教育行业数字化…

SpringMVC08、Json

8、Json 8.1、什么是JSON&#xff1f; JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式&#xff0c;目前使用特别广泛。采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和…

LeetCode 173.二叉搜索树迭代器

实现一个二叉搜索树迭代器类BSTIterator &#xff0c;表示一个按中序遍历二叉搜索树&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在…

探索机器学习的无限可能性:从初学者到专家的旅程

探索机器学习的无限可能性&#xff1a;从初学者到专家的旅程 在当今数字时代&#xff0c;机器学习无疑是最引人注目的技术之一。它已经深入到我们生活的方方面面&#xff0c;从个性化推荐到自动驾驶汽车&#xff0c;再到医疗诊断和金融预测。但是&#xff0c;即使我们已经见证…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:RotationGesture)

用于触发旋转手势事件&#xff0c;触发旋转手势的最少手指为2指&#xff0c;最大为5指&#xff0c;最小改变度数为1度。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 接口 RotationGesture(value?: …

三、N元语法(N-gram)

为了弥补 One-Hot 独热编码的维度灾难和语义鸿沟以及 BOW 词袋模型丢失词序信息和稀疏性这些缺陷&#xff0c;将词表示成一个低维的实数向量&#xff0c;且相似的词的向量表示是相近的&#xff0c;可以用向量之间的距离来衡量相似度。 N-gram 统计语言模型是用来计算句子概率的…

docker 子网

当需要给容器分配指定 ip &#xff0c;为避免ip 冲突&#xff0c;指定容器子网处理 创建 subnet 子网 docker network create --subnet 10.0.0.0/24 --gateway 10.0.0.1 subnet-testdocker network ls NETWORK ID NAME DRIVER SCOPE ... f582ecf297bc sub…