Java数据结构之AVL树详解

java实现平衡二叉树 平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树,可以保证查询效率较高。具有以下特点: 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。举例说明, 看看下面哪些AVL树,为什么?平衡二叉搜索树的左右子树,高度差不能大于1,所以前两个满足。... 阅读详情

​

Java数据结构之AVL树详解 本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(AVL树)的相关知识,AVL树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。

AVL树的引入

搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以下极端情况: 这样的二叉树搜索效率甚至比链表还低。在搜索二叉树基础上出现的平衡二叉树(AVL树)就解决了这样的问题。当平衡二叉树(AVL树)的某个节点左右子树高度差的绝对值大于1时,就会通过旋转操作减小它们的高度差。

基本概念

AVL树本质上还是一棵二叉搜索树,它的特点是:

  1. 本身首先是一棵二叉搜索树。

  2. 每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)。

  3. 当插入一个节点或者删除一个节点时,导致某一个节点的左右子树高度差的绝对值大于1,这时需要通过左旋和右旋的操作使二叉树再次达到平衡状态。

平衡因子(balanceFactor)

  • 一个结点的左子树与右子树的高度之差。

  • AVL树中的任意结点的BF只可能是-1,0和1。

基础设计

下面是AVL树需要的简单方法和属性:

public class AVLTree <E extends Comparable<E>>{ class Node{ E value; Node left; Node right; int height; public Node(){} public Node(E value){ this.value = value; height = 1; left = null; right = null; } public void display(){ System.out.print(this.value + " "); } } Node root; int size; public int size(){ return size; } public int getHeight(Node node) { if(node == null) return 0; return node.height; } //获取平衡因子(左右子树的高度差,大小为1或者0是平衡的,大小大于1不平衡) public int getBalanceFactor(){ return getBalanceFactor(root); } public int getBalanceFactor(Node node){ if(node == null) return 0; return getHeight(node.left) - getHeight(node.right); } //判断一个树是否是一个平衡二叉树 public boolean isBalance(Node node){ if(node == null) return true; int balanceFactor = Math.abs(getBalanceFactor(node.left) - getBalanceFactor(node.right)); if(balanceFactor > 1) return false; return isBalance(node.left) && isBalance(node.right); } public boolean isBalance(){ return isBalance(root); } //中序遍历树 private void inPrevOrder(Node root){ if(root == null) return; inPrevOrder(root.left); root.display(); inPrevOrder(root.right); } public void inPrevOrder(){ System.out.print("中序遍历:"); inPrevOrder(root); }}

RR(左旋)

    往一个树右子树的右子树上插入一个节点,导致二叉树变得不在平衡,如下图,往平衡二叉树中插入5,导致这个树变得不再平衡,此时需要左旋操作,如下: 代码如下:

//左旋,并且返回新的根节点 public Node leftRotate(Node node){ System.out.println("leftRotate"); Node cur = node.right; node.right = cur.left; cur.left = node; //跟新node和cur的高度 node.height = Math.max(getHeight(node.left),getHeight(node.right)) + 1; cur.height = Math.max(getHeight(cur.left),getHeight(cur.right)) + 1; return cur; }

LL(右旋)

   往一个AVL树左子树的左子树上插入一个节点,导致二叉树变得不在平衡,如下图,往平衡二叉树中插入2,导致这个树变得不再平衡,此时需要左旋操作,如下: 代码如下:

//右旋,并且返回新的根节点 public Node rightRotate(Node node){ System.out.println("rightRotate"); Node cur = node.left; node.left = cur.right; cur.right = node; //跟新node和cur的高度 node.height = Math.max(getHeight(node.left),getHeight(node.right)) + 1; cur.height = Math.max(getHeight(cur.left),getHeight(cur.right)) + 1; return cur; }

LR(先左旋再右旋)

    往AVL树左子树的右子树上插入一个节点,导致该树不再平衡,需要先对左子树进行左旋,再对整棵树右旋,如下图所示,插入节点为5.

RL(先右旋再左旋)

    往AVL树右子树的左子树上插入一个节点,导致该树不再平衡,需要先对右子树进行右旋,再对整棵树左旋,如下图所示,插入节点为2.

添加节点

//添加元素 public void add(E e){ root = add(root,e); } public Node add(Node node, E value) { if (node == null) { size++; return new Node(value); } if (value.compareTo(node.value) > 0) { node.right = add(node.right, value); } else if (value.compareTo(node.value) < 0) { node.left = add(node.left, value); } //跟新节点高度 node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1; //获取当前节点的平衡因子 int balanceFactor = getBalanceFactor(node); //该子树不平衡且新插入节点(导致不平衡的节点)在左子树的左子树上,此时需要进行右旋 if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) { return rightRotate(node); } //该子树不平衡且新插入节点(导致不平衡的节点)在右子树子树的右子树上,此时需要进行左旋 else if (balanceFactor < -1 && getBalanceFactor(node.right) <= 0) { return leftRotate(node); } //该子树不平衡且新插入节点(导致不平衡的节点)在左子树的右子树上,此时需要先对左子树左旋,在整个树右旋 else if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) { node.left = leftRotate(node.left); return rightRotate(node); } //balanceFactor < -1 && getBalanceFactor(node.left) > 0 //该子树不平衡且新插入节点(导致不平衡的节点)在右子树的左子树上,此时需要先对右子树右旋,再整个树左旋 else if(balanceFactor < -1 && getBalanceFactor(node.right) > 0) { node.right = rightRotate(node.right); return leftRotate(node); } return node; }

删除节点

//删除节点 public E remove(E value){ root = remove(root,value); if(root == null){ return null; } return root.value; } public Node remove(Node node, E value){ Node retNode = null; if(node == null) return retNode; if(value.compareTo(node.value) > 0){ node.right = remove(node.right,value); retNode = node; } else if(value.compareTo(node.value) < 0){ node.left = remove(node.left,value); retNode = node; } //value.compareTo(node.value) = 0 else{ //左右节点都为空,或者左节点为空 if(node.left == null){ size--; retNode = node.right; } //右节点为空 else if(node.right == null){ size--; retNode = node.left; } //左右节点都不为空 else{ Node successor = new Node(); //寻找右子树最小的节点 Node cur = node.right; while(cur.left != null){ cur = cur.left; } successor.value = cur.value; successor.right = remove(node.right,value); successor.left = node.left; node.left = node.right = null; retNode = successor; } if(retNode == null) return null; //维护二叉树平衡 //跟新height retNode.height = Math.max(getHeight(retNode.left),getHeight(retNode.right)); } int balanceFactor = getBalanceFactor(retNode); //该子树不平衡且新插入节点(导致不平衡的节点)在左子树的左子树上,此时需要进行右旋 if (balanceFactor > 1 && getBalanceFactor(retNode.left) >= 0) { return rightRotate(retNode); } //该子树不平衡且新插入节点(导致不平衡的节点)在右子树子树的右子树上,此时需要进行左旋 else if (balanceFactor < -1 && getBalanceFactor(retNode.right) <= 0) { return leftRotate(retNode); } //该子树不平衡且新插入节点(导致不平衡的节点)在左子树的右子树上,此时需要先对左子树左旋,在整个树右旋 else if (balanceFactor > 1 && getBalanceFactor(retNode.left) < 0) { retNode.left = leftRotate(retNode.left); return rightRotate(retNode); } //该子树不平衡且新插入节点(导致不平衡的节点)在右子树的左子树上,此时需要先对右子树右旋,再整个树左旋 else if(balanceFactor < -1 && getBalanceFactor(retNode.right) > 0) { retNode.right = rightRotate(retNode.right); return leftRotate(retNode); } return retNode; }

以上就是Java数据结构之AVL树详解的详细内容!

​

Java——二叉树 平衡因子可以是 -1、0 或 1,这确保了每个节点的左右子树的高度差不会超过 1,从而维持了树的平衡状态。AVL树是一种高度平衡的二叉搜索树,它在每次插入或删除节点后,都会通过旋转操作来保持树的平衡。AVL树的主要优点是在保持平衡的同时,还能保持二叉搜索树的性质,因此在查找、插入和删除操作时具有较高的效率。红黑树是一种特殊的二叉查找树,它的每个节点都有一个颜色属性,要么是红色,要么是黑色。:当一个节点的平衡因子变为非法值时,如果不平衡在节点的某一侧,那么只需要一次旋转就可以恢复平衡。 阅读详情

相关推荐

[UE5蓝图基础二]1.[1d混合空间] 走和跑的动画切换(shift切换)

再双击”run”进去 我们需要给他指定一个动画姿势,这里就需要给他我们前面做的”1d”混合空间,然后可以看到”1d” 上有个speed参数,代表的速度 从前面的逻辑来看需要通过控制速度来切换动画,那么必然不能写死速度,把速度提升为变量传递进来即可,所以就得到以下蓝图节点。混合空间的概念:混合空间就是可以将角色多个动画混合在一起 ,我们创建动画类就是创建个”Animation”文件夹 在文件夹内创建混合空间。我们目前要实现的是一个走和跑的功能 那么创建1d即可。到这一步混合空间已经做完 下一步做”动画蓝图”

qq_30584617的博客 3300

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

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

m0_62969222的博客 3691

CTFmisc-------Jack

每一个文件里面都有不一样的base64编码,我尝试将其解密,发现解出来的是乱码,所以我想到真正的flag藏在这些字符串中,所以我们要写代码把字符串提取出来。提取出来后,得到很多的base64的编码,要一个一个的解码很麻烦,猜到里面有flag字样的base64编码,所以我们将flag进行base64编码,1.下载得到Jack文件夹,里面有很多的txt文件。发现这个字符串是众多编码中唯一一个没有==然后从那些base编码中寻找Zmxh字段。

woshicainiao666的博客 1万+

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

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

weixin_63541561的博客 1647

数字化车间智能排产调度挑战赛(一)—— 数学模型

科大讯飞——数字化车间智能排产调度挑战赛。

Lyyyp的博客 5653

双向全桥隔离DC-DC变换器(DAB)的调制优化与挑战解析

本文深入解析了双向全桥隔离DC-DC变换器(DAB)的核心调制技术及其面临的挑战。文章从基础的相移调制(SPS)入手,逐步探讨了扩展相移(EPS)、双重相移(DPS)等进阶策略,并重点分析了电流优化与零电压开通(ZVS)等硬核优化技巧。针对DAB在实际应用中存在的建模困难、多模块并联及数字实现等挑战,提供了实用的应对策略与设计思路,旨在帮助工程师在性能、复杂度与成本之间找到最佳平衡。

weixin_29271053的博客 573

平衡二叉树(java)

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

一起coding,一起嗨。 1885

别再死记硬背了!用MaxDEA软件实操SBM、DDF、NDDF模型,手把手教你测算绿色全要素生产率

本文深度解析如何使用MaxDEA软件实操SBM、DDF、NDDF模型,手把手教你测算绿色全要素生产率(GTFP)。通过详细的模型选择对比、数据准备策略和MaxDEA操作流程,帮助研究者科学构建指标体系并准确解读结果,提升环境管理研究的实证分析能力。

weixin_28731231的博客 316

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

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

BugMan的博客 1812

STM32F4使用CUBEMX ADC定时采样+DMA

STM32、FFT、ADC、TIM

m0_62379750的博客 4224

Apifox 自动化测试新增流程控制条件,复杂测试场景不再是问题

在 if 条件后的输入框填写请求接口得到的变量 viewed ,选择条件为「小于」,输入比较数值 10 ,并在 if 条件下添加「宠物下架处理」步骤。借助新增的自动化测试流程控制条件,测试人员就可以使用 Apifox 去实现更深层更多样的测试应用场景,帮助提升测试效率,减少复杂场景的测试操作。「查询新建宠物」、「修改宠物状态为已售出」和「查询宠物状态是否修改」步骤为当前在售宠物信息盘点的三个标准步骤,所以将这三个步骤合成一组。在循环中添加「查询在售宠物」和「修改宠物状态」步骤;

878

数据结构 - 从二叉搜索树说到AVL树(二)之AVL树的操作与详解(Java)

  写在前:我在尽可能的写一篇能比较清晰且完整的讲完整个AVL树操作的文章,所有文字以及例图都是我一笔一划写出来的。由于AVL树的操作包含了查找,删除,插入操作,除了一些规律之外,一些处理细节,比如旋转操作,失衡时候的调整步骤等,除了死记硬背没有别的办法,所以我建议读者可以拿起笔,集中精神,跟着思路一口气看完,因为一些操作麻烦,走马观花的阅读势必会多花不必要的精力,不如一次性掌握起来,这...

aqm63700的博客 277

STM32 驱动直流无刷电机(BLDC)发声

STM32 驱动直流无刷电机(BLDC)发声

perseverance51博客 3403

Java集合和数据结构-详解AVL树VS红黑树:平衡之道大揭秘

AVL树和红黑树是两种重要的自平衡二叉搜索树,它们通过不同机制确保树高度维持在O(logn)级别,从而保证查找、插入和删除操作的高效性。AVL树采用严格的平衡策略,要求每个节点的左右子树高度差不超过1,通过四种旋转操作来维持平衡,这使得它的查找性能最优但插入删除开销较大。红黑树则通过五条着色规则实现相对宽松的平衡,最长路径不超过最短路径的两倍,虽然查找稍慢但插入删除操作更高效。两种树各有优势:AVL树适合查找密集型场景,而红黑树因其综合性能优异被广泛应用于Java集合框架、C++ STL和操作系统内核等核心

道冲而用之或不盈,渊兮似万物之宗。 1140

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

数据结构 - 从二叉搜索树说到AVL树(一)之二叉搜索树的操作与详解(Java)

  二叉搜索树(Binary Search Tree),简称BST,顾名思义,一颗可以用于搜索的二叉树。BST在数据结构中占有很重要的地位,一些高级树结构都是其的变种,例如AVL树、红黑树等,因此理解BST对于后续树结构的学习有很好的作用。同时利用BST可以进行排序,称为二叉排序,也是很重要的一种思想。   二叉树的性质:任意一个节点的所有左子树元素都比该元素值要小,而所有右子树元素都...

aqm63700的博客 367

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

阿里钉钉、天猫、同程、百度春招暑期Java实习重点面经综合(已拿offer)

什么是索引: 索引(Index)是帮助MySQL高效获取数据的数据结构,常见的查询算法,顺序查找,二分查找,二叉排序查找,哈希散列法,分块查找,平衡多路搜索树B树,索引是对数据库表中一个或多个列的数据进行排序的结构,建立索引有助于快速获取信息。索引也不是越多越好,创建索引也需要耗费资源,一是增加了数据库的存储空间,二是在插入和删除时要花费较多的时间去维护索引。 索引加快了查找速度 索引会降低插入、删除、修改等维护任务的速度 唯一索引可以确定每一行数据的唯一性 通过使用索引,可以在查询的过程中使用优化隐藏器

weixin_44976835的博客 900

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

数据结构与算法

二叉搜索树是一种。

qq_29676849的博客 865

红黑树原理与应用:从2-3-4树到高效数据结构

红黑树是一种自平衡二叉搜索树,通过颜色标记和旋转操作维持近似平衡。其核心思想源自2-3-4树的多叉结构,用红黑节点分别表示合并状态和独立节点,确保操作时间复杂度稳定在O(log n)。这种数据结构在需要频繁插入删除的场景中表现优异,如Linux进程调度器CFS和Java的TreeMap实现都采用了红黑树。理解红黑树的五条性质及其平衡原理,对于实现高效索引和实时系统至关重要。通过分析红黑树与AVL树、B树的特性对比,可以更好地选择适合不同应用场景的树形结构。

weixin_30387423的博客 273

红黑树原理、实现与应用全解析

红黑树是一种高效的自平衡二叉查找树,通过特定的颜色规则和旋转操作维持近似平衡。其核心原理在于保证从根节点到任意叶子节点的路径中黑色节点数量相同(黑高一致),从而确保最坏情况下时间复杂度仍为O(log n)。相比AVL树更宽松的平衡条件,红黑树在插入删除时减少旋转次数,在Java集合框架(如TreeMap)和操作系统(如Linux进程调度)等需要频繁更新的场景中表现优异。数据结构与算法实践中,红黑树通过变色、旋转等操作实现动态平衡,是理解高级数据结构和优化系统性能的重要基础。

437

2024042501-tree-avl

AVL树历史在计算机科学中,AVL 树以其两位苏联发明家Georgy Adelson-Velsky和 Evgenii Landis的名字命名,他们在 1962 年的论文“信息组织算法”中发表了它。它是一种自平衡二叉搜索树(BST),这是发明的第一个这样的数据结构。

qq_24428851的博客 1165

AVL树(Java)

目录一、什么是AVL树二、AVL树的实现AVL树的节点AVL树的插入AVL树的旋转右单旋左单旋左右双旋 右左双旋AVL树的验证三、AVL树的性能分析在了解什么是AVL树之前,我们先回顾二叉搜索树的概念二叉搜索树(二叉排序树),它或是一棵空树,或具有以下性质:根据二叉搜索树的性质,我们可以发现:1. 二叉搜索树中最左侧的节点是树中最小的节点,最右侧的节点是树中最大的节点2. 若采用中序遍历二叉搜索树,则可得到一个有序的序列二叉搜索树最主要的作用就是用于进行查询:当二叉搜索树是一颗完全二叉树时:其查询的平均查找

2301_76161469的博客 3185

Java 数据结构篇-实现 AVL 树的核心方法

AVL 树的说明、AVL 树的成员变量及其构造方法、实现 AVL 树的核心方法、实现 AVL 树的完整代码

小扳手 7363

数据结构[一] 平衡二叉树 AVL树结构详解 [Java实现]

博客思维导图 简述 先不说平衡二叉树,我们单开来说,这样比较方便理解。 先说二叉树,再说平衡条件,没那么多花里胡哨的理论,我只是想让大家看完能明白,能写出来 二叉树 什么是二叉树?二叉树数据结构,顾名思义,只有两个叉,在数据结构中,操作性能要远高于线性结构,有O(height)的索引性能。与线性结构有相同的空间复杂度,特性如下: 每个节...

zhang6622056的专栏 1224

数据结构之AVL树

AVL树的概念、AVL树的插入、删除、证明一棵二叉树是二叉搜索树、AVL树的性能分析

我要学编程的博客 2060

AVL树详解及Java实现

AVL的平衡原理分析及实现

thehazardon的博客 1295
上一篇: 完全掌握java之String类
下一篇: 让这篇4000字长文告诉你什么是TCP 序列号和确认号
Java_LingFeng
博客等级 码龄4年 505粉丝 259原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值