Java集合源码分析之基础(五):平衡二叉树(AVL Tree)

【python】geopandas库安装出现各种问题?可以看看这篇文章 geopandas的安装方法 阅读详情

二叉排序树很好的平衡了插入与查找的效率,但不平衡的二叉排序树效率大打折扣。今天介绍的AVL树就是一种解决此问题的方案。

定义

平衡二叉树(Self-Balancing Binary Search Tree 或Height-Balanced Binary Search Tree),是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1 。它是一种高度平衡的二叉排序树。意思是说,要么它是一棵空树,要么它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1 。我们将二叉树上结点的左子树深度减去右子树深度的值称为平衡因子BF (Balance Factor),那么平衡二叉树上所有结点的平衡因子只可能是-1 、0 和1。

如下图就不是一棵AVL树,因为结点18的左子树高度为2,右子树高度为0,高度差大于1。

 

不平衡

但通过一定的步骤调整之后,可以将其转为一棵平衡二叉树,如下图:

平衡二叉树

实现原理

平衡二叉树构建的基本思想就是在构建二叉排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。最小不平衡子树是指距离插入结点最近的,且平衡因子的绝对值大于1 的结点为根的子树。

下面通过一个实例,了解平衡二叉树的构建过程。

假如我们要将数组int[] a = {3, 2, 1, 4, 5, 6, 7, 10, 9, 8}构建成一棵二叉排序树,如果直接按照二叉排序树的定义,会得到下面的结果:

二叉排序树

这样的结果对查找是十分不利的,树的高度达到了8,而且大多数只有一个孩子。所以我们需要一些操作,将它变成一棵AVL树。

首先,插入元素3和2时,没有什么影响,此时3的平衡因子为1,2的平衡因子为0,结果如下:

 

插入3和2

现在,要把1插入树中,这时结果如下所示:

插入1

此时3的平衡因子为2了,不再符合平衡二叉树的规则。此时,整棵树就是最小不平衡子树,我们将其右旋:

右旋

再插入4,也不会影响平衡,结果如下:

插入4

此时,插入元素5,以3为根结点的子树成为了最小不平衡子树,如下所示:

插入5

现在要对其进行左旋:

左旋

现在继续插入元素6,此时以2为根结点的右子树为最小不平衡子树,结果如下:

插入6

这时再次需要对其进行左旋,这次旋转后要将4的左孩子变为2的右孩子,以满足二叉排序树的定义,如下所示:

 

左旋

再插入7时,情况和之前有些类似了,结果如下:

插入7

左旋后结果如下:

左旋

现在,继续插入10,此时无需调整,结果如下:

插入10

下一步,插入元素9,此时结果如下:

插入9

按照之前的经验,这时我们应该进行左旋了,但是左旋之后9将变为10的右孩子,这会不符合二叉排序树的定义。和之前不同的是,7和10的平衡因子符号相反,这是造成这一结果的原因。这种情况下,要先以10为根节点右旋,再进行左旋,结果如下所示:

 

右旋

 

左旋

最后插入元素8,如下所示:

 

插入8

此时情况和上述类似,6是最小不平衡子树的根结点,9和6的平衡因子符号相反,所以先以9为根结点右旋:

 

右旋

然后再以6左旋:

 

左旋

可以看到,此树的高度仅为4,与之前的8相差很多,性能自然也好很多。

平衡二叉树的删除操作与插入类似,这里将不再介绍。大家可以自己思考如何最高效地删除元素,可以分叶结点、仅有一个子结点和有两个子结点三种情况考虑,这里还用到了递归的思想。

接下来我们将介绍另一种实现方式,红黑树。

 

vue3 - element-plus表格组件el-table实现鼠标拖曳排序功能,vue3 Table表格拖拽排序,表格每行使用鼠标拖动进行排序功能,表格拖拽排序实现(详细示例代码,一键复制开箱即用 vue3,elementPlus,el-table,typescript,表格组件,Table表格,表格拖动排序,表格拖曳排序,鼠标拖拽表格进行排序功能,elementplus表格如何实现拖动每行进行排序操作,表格拖动改变顺序,鼠标拖曳,表格内的数据项拖拽排序,vue3如何实现element-Plus表格组件进行表格内的数据项拖拽排序,列表拖拽排序效果,实现table动态拖拽,鼠标拖着排序,vue3 element Plus 表格拖曳拖动拖拽 排序,el-table拖拽排序实现,表格内容拖拽重新排序,树形表 阅读详情

相关推荐

【python科研数据处理】将Endnote自动搜索的所有pdf文件,全都移动指定文件夹中

将Endnote自动搜索到的全部pdf文件,全都移动指定文件夹中1 背景2 问题解决 手动反爬虫,禁止转载:原博地址 https://blog.csdn.net/lys_828/article/details/122370892(CSDN博主:Be_melting) 知识梳理不易,请尊重劳动成果,文章仅发布在CSDN网站上,在其他网站看到该博文均属于未经作者授权的恶意爬取信息 1 背景 在进行期末考试周后,面对最后一门功课,需要提交至少80篇SCI参考文献,因此最快下载文献的方式就是通过Web of S

lys_828的博客 1801

平衡二叉树java实现

转载请注明出处! 一、概念 平衡二叉树是一种特殊的二叉搜索树,关于二叉搜索树,请查看上一篇博客二叉搜索树的java实现,那它有什么特别的地方呢,了解二叉搜索树的基本都清楚,在按顺序向插入二叉搜索树中插入值,最后会形成一个类似链表形式的树,而我们设计二叉搜索树的初衷,显然是看中了它的查找速度与它的高度成正比,如果每一颗二叉树都像链表一样,那就没什么意思了,所以就设计出来了平衡二叉树,相...

weixin_30699465的博客 757

YOLOv13改进策略【Head】| (独家改进)结合 ICME-2024 中的PPA注意力模块,自研带有注意力机制的小目标检测头

本文记录的是利用PPA (并行补丁感知注意模块)改进YOLOv13的检测头。通过改进传统卷积,形成带有注意力机制的小目标检测头,使模型能够更好地关注小目标的重要信息。HCF-Net: Hierarchical Context Fusion Network for Infrared Small Object Detection采用多分支特征提取策略,通过不同分支提取不同尺度和层次的特征。利用局部、全局和串行卷积分支,对输入特征张量进行处理。通过控制 patch size参数实现局部和全局分支的区分,计算非重叠

Limiiiing的博客 438

平衡二叉树(AVL)java实现+图解】

一种自平衡二叉搜索树,它是在每个节点上增加一个平衡因子,然后通过调整树中节点的高度来保持树的平衡。平衡因子是左子树的高度减去右子树的高度,用它可以表示出当前节点的平衡程度。删除:每删除一个节点后,也需要更新输的高度,平衡因子可能改变,依据平衡因子对二叉树进行调整。添加:每次添加一个节点后更新输的高度,平衡因子可能改变,依据平衡因子对二叉树进行调整;判断是否是平衡二叉树:通过判断每个子树的平衡因子的是否在[-1,1]区间内。,当一个节点的平衡因子绝对值大于1时,这个节点就被称为不平衡节点。

weixin_63541561的博客 1640

程序员修炼手册--AVLTree实现--附源代码

AVLtree三叉链实现

c-and-c++ It*s my life 421

Java数据结构——平衡二叉树(AVL)

AVL树的引入 搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以下极端情况: 这样的二叉树搜索效率甚至比链表还低。在搜索二叉树基础上出现的平衡二叉树(AVL)就解决了这样的问题。当平衡二叉树(AVL)的某个节点左右子树高度差的绝对值大于1时,就会通过旋转操作减小它们的高度差。 基本概念 AVL树本质上还是一棵二叉搜索树,它的特点是: 本身首先是一棵二叉搜索树。 每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)

m0_62969222的博客 3685

Java集合源码分析):平衡二叉树AVL Tree

在上一章的文章中,我们讲到了二叉排序树,它很好的平衡了插入与查找的效率,但二叉排序树如果不平衡,那么查找效率就会大大降低,今天要讲的这个平衡二叉树就是一种解决这个问题的方法。 一、平衡二叉树的定义 平衡二叉树 是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1 。它是一种高度平衡的二叉排序树。意思是说,要么它是一棵空树,要么它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1 。我们将二叉树上结点的左子树深度减去右子树深度的值称为平衡因子BF (Balance Fac

不会编程的派大星的博客 318

平衡二叉树 java_Java集合源码分析基础):平衡二叉树AVL Tree

二叉排序树很好的平衡了插入与查找的效率,但不平衡的二叉排序树效率大打折扣。今天介绍的AVL树就是一种解决此问题的方案。定义平衡二叉树(Self-Balancing Binary Search Tree 或Height-Balanced Binary Search Tree),是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1 。它是一种高度平衡的二叉排序树。意思是说,要么它是一棵空...

weixin_28868927的博客 136

Java从头开始到光头结束】No7.回顾Map集合基础与树形数据结构

Map集合基础与树形数据结构1.Map集合基础2.简述树形数据结构 基础回顾 → Map集合基础与树形数据结构 ———————————————————————————————————— 文章部分内容选自书本《码出高效:Java开发手册》 1.Map集合基础 之前的博客中已经对List集合中的ArrayList及LinkedList有过源码的大致分析和学习拓展,今天这篇博文主要是Map集合的一个铺垫(因为是回顾,所以不会有很基础的概念),之后我们会对Map集合中的常用实现类进行源码分析和学习。附上之前博客

菲林都已拆走 613

Java集合源码分析基础(六):红黑树(RB Tree

红黑树和AVL树的思想是类似的,都是在插入过程中对二叉排序树进行调整,从而提升性能,它的增删改查均可以在O(lg n)内完成。 本文会从定义到实现一棵红黑树展开,还会简单介绍其与AVL树的异同。 定义 红黑树是一棵二叉排序树。且满足以下特点: 1. 每个节点或者是黑色,或者是红色。 2. 根节点是黑色。 3. 每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或...

i_love_lu的博客 221

数据结构与算法总结

(一) 数据结构 列举java集合以及集合之间的继承关系: 容器类介绍以及之间的区别(Java容器主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections)) List,Set,Map的区别:List能插入重复对象,可插入多个Null元素;Set不允许有重复对象,能有一个Null元素,set是无序的,但TreeSet 能进行排序;Map是一个接口,并不是collection的子接口或实现类,ke.

风和先行的专栏 291

java实现 AVLTreeAVL树 ,包含源码、注释、说明

温馨提示: 该AVLTree继承自我之前写的BinarySearchTree(二叉平衡树),所以没有看我之前的的BinarySearchTree(二叉平衡树))的小伙伴需要去看看,要不然有些地方你可能会看不懂哦。 说明: 每个方法的作用,在源码的注释中,我已经写的非常详细了,这里就略过了。在这里我主要想要介绍VALTree中一些特有的方法,或者说重写的方法 第一个就是再添加节点之后的操作,封装成addAfterOpt(Node node)方法 第二个就是再删除节点之后的操作,封装成removeAfter

✈ 正在努力 の 寒江(StudiousTiger) ✌ 呐 ✈ 587

平衡二叉树(java)

平衡二叉树也叫平衡二叉搜索树 (Self-balancingbinarysearch tree) 又被称为AVL树,可以保证查询效率较高。具有以下特点:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1.并且左右两个子树都是一棵平衡二叉树

一起coding,一起嗨。 1871

平衡二叉树Java

1)平衡二叉树也叫平衡二叉搜索树(Self-balancingBinarySearchTree)又被称为AVL树,可以保证查询效率较高2)具有以下特点:它是一颗空树或它的左右两个子树的高度差绝对值不超过1,并且左右两颗子树都是一颗平衡二叉树平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树。

weixin_48544279的博客 777

Java与数据结构——平衡二叉树AVL

给定数列{ 10,12,8,9,7,6 },构建 AVL 树,当插入 6 时,发现 leftHeight - rightHeight > 1 ,此时不再是一个 AVL 树,进行。:给定数列{ 4,3,6,5,7,8 },构建 AVL 树,当插入 8 时,发现 rightHeight - leftHeight > 1 ,此时不再是一个 AVL 树,进行。(3)把新节点的右子树设置成当前节点的右子树的左子树,newNode.right = this.right.left;

u012621831的博客 1401

数据结构(6)树形结构——平衡二叉树JAVA代码实现)

平衡二叉树的概念,平很二叉树的LL、RR、RL、LR旋转,以及JAVA版本的AVL树的实现。

BugMan的博客 1793

Java数据存储结构——平衡二叉树

平衡二叉树的特点: - 二叉树左右两个子树的高度差不超过1 - 任意节点的左右两个子树都是一颗平衡二叉树 在原来的平衡二叉树中,新增数据会破坏平衡性,所以需要进行旋转最小不平衡子树保持平衡。

Java技术加油站的博客 888

EDA工具,modelsim

适用于从事EDA行业,FPGA,芯片行业

MX1.25mm的各引脚封装3D

MX1.25mm的各引脚封装3D

上一篇: Java集合源码分析之基础(四):二叉排序树
下一篇: 大专学历屌丝码农如何在互联网寒冬找到35k的工作
刀哥谈Java
博客等级 码龄7年 110粉丝 84原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值