平衡二叉树AVL及其旋转

平衡二叉树(AVL)的插入和删除详解(下) 平衡二叉树(AVL)的插入和删除详解(上):http://blog.youkuaiyun.com/sysu_arui/article/details/7897017 1、测试代码 为减小篇幅,只给出了主程序,其他函数模块请看(上)中的描述。 #include #include #include using namespace std; int main(int argc, char *ar 阅读详情

平衡二叉树的定义:

1. 平衡二叉树是一棵二叉查找树,满足所有二叉查找树的性质

2. 平衡二叉树要求任意一个节点的左右子树的高度差不能超过1

对于高度差,有一个专有名词平衡因子。

平衡因子:左子树的高度减去右子树的高度,及B = B左 - B右。由平衡二叉树的定义可知,平衡因子的取值只可能为0,1,-1。0:左右子树等高。1:左子树比较高。-1:右子树比较高。

高度:树中层级的数量。比如只有 Level 0,Level 1,Level 2 则高度为 3。一般的我们取叶子节点的高度值为1,任意一个节点的高度值取左右子树比较高的那个孩子节点的高度值然后加1。

层级:根为 Level 0 层,根的子节点为 Level 1 层,以此类推。


AVL的失衡情况

前面我们介绍了AVL的高度和平衡因子问题,接下来我们来看看有几种情况会导致AVL的失衡,也就是什么情况下我们需要调整AVL树,使其经过调整后能继续维持平衡状态。

对于AVL,需要进行再平衡操作的情况正如以上4个图所示。对应下面4种描述

插入位置如何调整
插入节点(0006)在发现者(0020)左子树的左边LL调整,右单旋
插入节点(0014)在发现者(0020)左子树的右边LR调整,左右双旋
插入节点(0033)在发现者(0020)右子树的右边RR调整,左单旋
插入节点(0025)在发现者(0020)右子树的左边RL调整,右左双旋

注:二叉平衡树在插入或删除一个结点时,先检查该操作是否导致了树的不平衡,若是,则在该路径上查找最小的不平衡树(即如果有多个结点同时不满足平衡,就选最靠近下面的那个结点作为最小的不平衡树,称为发现者),调节其平衡。

注2:LL,LR,RR,RL调整仅仅是表示插入结点相对于发现结点的位置,而旋转方向,我认为是针对旋转点的位置变化而言的。

对于单旋,旋转点为发现者,左旋:发现者及其左子节点向下移动,右节点向上移动。右旋:发现者及其右子节点向右下沉。同时维护处理其他节点间的关联关系。

对于双旋如LR,是先以发现节点的左节点左旋,再以发现节点右旋。

这里也存在不同的说法,如LL是左单旋,我这里是为了方便自己的理解,其实意义一致。

旋转逻辑用代码展现,如下(后面会贴上完整代码)

        int rHeight = height(parent.right);
        int lHeight = height(parent.left);
        //当添加完一个结点后,如果:(右子树的高度-左子树的高度)>1,左旋转
        if (rHeight - lHeight > 1) {
            //如果它的右子树的左子树高度大于它的左子树高度,双旋转
            if (parent.right != null && height(parent.right.left) > lHeight) {
                //先对这个结点的右节点进行右旋转
                rightRotate(parent.right);
            }
            //再对当前结点进行左旋转即可。
            leftRotate(parent);
        }
        //当添加完一个结点后,如果:(左子树的高度-右子树的高度)>1,右旋转
        else if (lHeight - rHeight > 1) {
            //如果它的左子树的右子树高度大于它的右子树高度,双旋转
            if (parent.left != null && height(parent.left.right) > rHeight) {
                //先对这个结点的左节点进行左旋转
                leftRotate(parent.left);
            }
            //再对当前结点进行右旋转即可。
            rightRotate(parent);
        }

算了,不写了,弄明白了,直接贴代码吧。其中Tree的代码在另一篇二叉树的文章中

package tree;

/**
 * 平衡二叉树(非递归版)
 */
public class AVLTree<V extends Comparable<? super V>> extends Tree<V> {

    @Override
    public Node insert(V v) {
        Node newNode = super.insert(v);
        // 找到最小失衡树
        Node parent = newNode;
        balance(parent);
        return newNode;
    }

    @Override
    public Node remove(V v) {
        Node remove = super.remove(v);
        balance(remove);
        return remove;
    }

    private void balance(Node parent) {
        while (parent != null) {
            if (Math.abs(height(parent.left) - height(parent.right)) > 1) {
                break;
            }
            parent = parent.parent;
        }
        if (parent == null) return;
        int rHeight = height(parent.right);
        int lHeight = height(parent.left);
        //当添加完一个结点后,如果:(右子树的高度-左子树的高度)>1,左旋转
        if (rHeight - lHeight > 1) {
            //如果它的右子树的左子树高度大于它的左子树高度,双旋转
            if (parent.right != null && height(parent.right.left) > lHeight) {
                //先对这个结点的右节点进行右旋转
                rightRotate(parent.right);
            }
            //再对当前结点进行左旋转即可。
            leftRotate(parent);
        }
        //当添加完一个结点后,如果:(左子树的高度-右子树的高度)>1,右旋转
        else if (lHeight - rHeight > 1) {
            //如果它的左子树的右子树高度大于它的右子树高度,双旋转
            if (parent.left != null && height(parent.left.right) > rHeight) {
                //先对这个结点的左节点进行左旋转
                leftRotate(parent.left);
            }
            //再对当前结点进行右旋转即可。
            rightRotate(parent);
        }
    }

}

 再附上测试代码,测试几组不同结构的二叉树:

测试结果验证无误,按自己的逻辑手写的,但是不保证有没有什么奇怪的bug未发现,欢迎指正

package tree;

import java.util.List;

public class Client {

    public static void main(String[] args) {
        Tree<Integer> tree = new AVLTree<>();
//        int[] arr = {5,4,6,3,2};
//        int[] arr = {10, 5, 20, 4, 7, 30, 40, 50};
//        int[] arr = {10, 5, 20, 2, 6, 1};
//        int[] arr = {5, 4, 3,};
//        int[] arr = {6, 7, 8};
//        int[] arr = {4, 3, 6, 5, 7, 8};
//        int[] arr = {7, 4, 8, 3, 5, 6};
//        int[] arr = {10, 5, 20, 15, 30};  
        int[] arr = {60, 10, 70, 5, 20, 15, 30};  // 这组数例子有些意思
        //循环添加结点到二叉排序树
        for (int tmp : arr) {
            tree.insert(tmp);
        }
        tree.remove(5);
        List<Integer> integers = tree.levelOrder(tree.getRoot());
        for (int i : integers) {
            System.err.println(i);
        }
    }
}

 

在Qt中使用EtherCAT-SOEM的初始化中,状态机卡在PreOp->Save-Op过程中,出现State=0x12, Error=0x001e错误的解决办法 1.在调试EtherCAT软件过程中,一直出现配置从站进不了Save_op状态,通过下函数检查从站状态: //使用的从站编号为1 只有1个从站 ec_slave[1].state = EC_STATE_SAFE_OP; ec_writestate(1); //设置到安全模式 ec_statecheck(1, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 4); printf("Slave %d State=0x%2.2x StatusCode=0x%4 阅读详情

相关推荐

Cadence IC618与Spectre231安装:环境变量与License配置详解

在Linux系统中部署Virtuoso等EDA工具时,环境变量与License管理是决定工具能否顺利启动的核心环节。环境变量决定了系统如何找到工具二进制文件以及工具如何定位自身资源,而License则通过FlexLM授权机制控制工具的使用权限。理解PATH、CDS_ROOT、CDS_LIC_FILE等关键变量的作用,掌握lmgrd服务与lmstat验证方法,能显著减少安装后启动失败的概率。无论是学生初装Cadence IC618与Spectre231,还是实验室工作站需要搭建可用的模拟设计环境,理顺环境变量

weixin_29192365的博客 372

平衡二叉树(AVL)定义及其旋转

平衡二叉树(AVL) 平衡二叉树(AVL),是一个二叉排序树,同时任意节点左右两个子树的高度差(或平衡因子,简称BF)的绝对值不超过1,并且左右两个子树也满足。 为什么使用平衡二叉树 通过二叉查找树的查找操作可以发现,一棵二叉查找树的查找效率取决于树的高度,如果使树的高度最低,那么树的查找效率也会变高。 如下面一个二叉树,全部由右子树构成 这个时候的二叉树其实就类似于链表,此时的查找时间复杂度为O(n),而AVL树的查找时间复杂度为O(logn)。之前讲过O(logn)耗时是小于O(n..

weixin_42640226的博客 1481

UE5.5 PCGFrameWork程序化内容生成实战指南

本文是UE5.5 PCGFrameWork程序化内容生成的实战指南。详细介绍了从点云采样、DynamicMesh几何生成到子图与蓝图扩展的核心工作流。通过实战案例演示如何利用该框架高效构建丰富的程序化场景,为技术美术、独立开发者及爱好者提供从入门到进阶的系统性指引。

tea88的博客 921

数据结构 | 平衡二叉树 AVL

1. 概念 平衡二叉树是一种特殊的二叉排序树,其左右子树都是平衡二叉树。所谓平衡,即节点的左右子树高度差不超过1。 平衡因子=左子树高度-右子树高度 对于平衡二叉树,树中所有节点的平衡因子的取值只能是-1、0、1三个值 2. 节点失衡原因及平衡调整问题 左旋 /** * 40 node 50 * \ 左旋 / \ * 50 child -》 40 60 * / \

BUZZ_Q的博客 589

企业微信群机器人Webhook配置全攻略:从创建到发送消息的完整流程

本文详细解析了企业微信群机器人的Webhook配置全流程,从创建机器人、获取关键Webhook地址,到使用代码发送文本、Markdown等多种消息类型。内容涵盖安全加固、错误处理及与CI/CD等系统集成的实战指南,帮助企业快速构建高效、稳定的内部通知系统。

ik678901的博客 1788

yolov5部署之七步完成tensorRT模型推理加速

目录前言step 1. 下载yolov5源码以及tensorrtx源码,并将yolov5s.pt转为.wts模型step 2. 确定并下载自己准备使用的CUDA版本。step 3. 根据自己的CUDA版本下载对应版本的cuDNN以及TensorRTstep 4. 根据自己使用的VS版本下载对应版本的OpenCVstep 5. 安装CUDAstep 6. 安装cuDNN、TensorRT以及验证TensorRT是否安装成功 前言     前段时间研究了Pytorch的环境配置,之后便从github上下载了yo

Christo的博客 4万+

数据结构期末复习——二叉平衡树(AVL树)的旋转

平衡树 要记得计算平衡因子。平衡因子为当前节点为根节点的子树的左右子树高度差。 插入、删除都会改变平衡因子。顺着操作的节点向上找到第一个平衡因子大于1的节点,经过的路径即为最小不平衡子树。最小不平衡子树最多只有3个节点。通过如下的旋转可以达到平衡的目的: 单旋 最简单的情况是,子树呈一条直线。 将中间的“拎起来”即可。 双旋 由于搜索树的性质,当不平衡子树出现“弯折”时,直接将中间的“拎起来”会破坏搜索树“左小右大”的性质。此时通过交换,将3个节点中大小处在中间的节点放到中间的位置,再由“左小右大”的性

qq_39561693的博客 351

蓝牙Mesh安全机制全解析:如何防止你的智能门锁被黑客控制?

本文深入解析蓝牙Mesh安全机制,重点探讨如何保护智能门锁免受黑客攻击。详细介绍了蓝牙Mesh的多层次安全架构,包括密钥管理体系、设备入网流程及实战防护策略,帮助用户构建更安全的智能家居网络。

h3i4j的博客 732

数据结构与算法学习之平衡二叉树(AVL树)

数据结构与算法学习之平衡二叉树(AVL树)

m0_55895641的博客 215

别再只画GO图了!用R语言+Perl脚本搞定单细胞KEGG富集分析与圈图(附完整代码)

本文详细介绍了如何利用R语言和Perl脚本实现单细胞KEGG富集分析全流程,从基因ID转换到专业圈图可视化。通过对比KEGG与GO分析的互补价值,提供完整的代码实现和优化技巧,帮助研究者高效完成单细胞测序数据的通路分析,并生成高质量的圈图展示结果。

weixin_28694169的博客 405

ubuntu系统禁止/开启内核自动更新

内核自动更新会导致驱动和内核版本不对应,导致驱动无法使用,所以需要禁止自动更新内核。本文介绍ubuntu系统禁止/开启内核更新的方法。

m0_50105717的博客 5289

平衡二叉树(AVL)的左旋转右旋转和双旋转

平衡二叉树的介绍 首先,咱们先来说一下为什么要提出平衡二叉树的概念,如果一个二叉排序树是一个只有左子树或者右子树的二叉排序树的时候,其实它就相当于一个链表,但是他的查询,删除,遍历的速度却没有链表快。这是为什么呢。因为在每次查询,删除,遍历的时候,要去判断他的左节点或者右节点是否为null,所以浪费了时间。所以我们提出平衡二叉树的概念 基本介绍 1)平衡二叉树也叫平衡二叉搜索树(Self-bala...

interesting_code的博客 2276

beegfs源码分析

BeeGFS的客户端是由一个内核模块和两个系统服务组成的,这里咱们主要分析内核模块。由于BeeGFS的目录树解析,是在父目录DEntry里找子目录或文件DEntry,逐级迭代完成的,所以在Mount文件系统时,须要从管理节点获取根元数据节点的ID,而后再向根元数据节点查询根目录的DEntry的信息,为后续的目录解析打下基础。获取类似/data/beeond/data/dentries/38/51/root/#fSiDs#/文件fileId的父路径。1.1 FileID的生成。Session网络消息。

wfzy的博客 1913

【数据结构笔记12】平衡二叉树,AVL树,RR旋转/LL旋转/LR旋转/RL旋转,AVL树插入的代码实现

平衡二叉树(AVL树)也是一种搜索树,因此插入元素后要及时进行调整。

记录学习痕迹的公众号:Piper蛋窝 1479

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

平衡二叉树 AVL树 双旋转

问题 若数组{1,2,3,4,5,6}组成二叉排序树 整棵树左子节点全为空 则相当于链表 而在实际操作中如增删查 效率还会更低 为了避免这种情况发生 需要对二叉排序树旋转 使左右子树高度差不超过1 基本介绍 平衡二叉树也叫平衡二叉搜索树(Self balancing binarysearch tree) 又被称为 AVL树,可以保证查询效率较高。 具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、T

Azadoo的博客 398

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

AVL 平衡二叉树旋转方法

1、预备知识定义树(tree)的一种自然的方式是递归的方式。一棵树使一些节点的集合。这个集合可以是空集;若不是空集,则树由称作根(root)的节点 r 以及 0 个或多个非空的(子)树 T1,T2,T3,…,Tk 组成。这些子树每一颗的根都被来自根 r 的一条有向的边所连结。每一颗子树的根叫做根 r 的儿子(child),而根 r 是每一颗子树的根的父亲(parent)。没有儿子的根叫做树叶(lea

Land is there, but I will build another Land 1万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

平衡二叉树(AVL树,AVL树旋转)

1、平衡因子(BF):BF = HL - HR(其中HL和HR分别是左子树和右子树的高度)。2、平衡二叉树(AVL树):对于任一结点,左右子树的高度差的绝对值是小于1。 即 |BF|<=1。例:1、 对于3这个结点来讲,左子树高度为2,右子树高度为0,左右子树高度差为2,2>1,所以该树不是平衡二叉树。2、 对于这个树里面的每一个结点来讲,左右子树的高度差都小于等于1,所以

beichengll的博客 4382

数据结构之平衡二叉树(AVL树,左旋转,右旋转,双向旋转)

引入:看一下案例(说明二叉排序树可能存在的问题) 数列{1,2,3,4,5,6},二叉排序树(BST)的形式为 平衡二叉树基本介绍 (1)平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree),又被称为AVL树,可以保证查询效率比较高. (2)具有以下特点 ...

qq_44962429的博客 1611

平衡二叉树(AVL)插入时的旋转操作(无代码)

平衡二叉树(AVL)插入时的旋转操作(无代码)前言一、平衡二叉树的定义二、引入两个概念1.最小不平衡子树根节点(简称:最小失衡点)2.旋转中心节点(简称:旋转中心)三、旋转的几种情况1、单旋转(LL、RR)LL旋转RR旋转2、双旋转(LR、RL)LR旋转RL旋转3、注意事项 前言 首先感谢下列文章为作者提供思路,其次本文为作者未来查阅所写。 平衡二叉树(AVL)图解与实现. 平衡二叉树的旋转. 平衡二叉树的LR旋转的两种情况. 本次作图使用下列网站资源: 数据结构可视化. 一、平衡二叉树的定义 平衡树(

qq_45887346的博客 493

AVL平衡二叉树旋转详解

AVL(平衡二叉树) AVL定义 左子树和右子树的高度之差的绝对值不超过1,高度之差也叫做平衡因子(Balance Factor),简称BF 左右子树也都是平衡二叉树 当一个节点没有左子树时,左子树高度为-1 当一个节点的左子树时叶子节点时,左子树的高度为0 当一个节点的左子树的左子树是叶子节点时,左子树的高度为1 # 如图所示: # 例1: 以2为根节点,左子树的高度为0,右子树的高度为1,0 - 1 = 1,满足平衡二叉树条件 -1 <= BF <= 1 # 例2: 以1为根节点,左右

zq_sir的博客 1498

关于左右子树的旋转,构建AVL平衡二叉树简单实现思路

这里关于AVL平衡二叉树的 左右子树进行旋转的方法做一个概述 一般来讲:当一个二叉排序树的左右子树高的差的绝对值大于1时,为了索引效率我们会考虑以某个结点为根节点的二叉树的左右子树考虑进行左旋转或者右旋转来达到索引优化的目的,也就是我们所说的AVL平衡二叉树 这里以从根节点开始举例 这是里构建二叉树的节点类的基本属性 class Node { int value; Node left; ...

qq_45894458的博客 364

有关AVL平衡二叉树的旋转

AVL 旋转」存在的目的是什么? http://www.zhihu.com/question/20390173 AVL平衡二叉树中旋转操作的本质及其实现 http://blog.youkuaiyun.com/vesper305/article/details/13614403 ...

cicuinie0996的博客 107

数据结构与算法之平衡二叉树(AVL)的插入、旋转以及遍历

平衡二叉树 (AVL,Balanced Binary Tree),简称平衡树 (AVL 树)-- 树上任一结点的左子树和右子树的高度之差不超过 1。 平衡二叉树的插入 假定有如下子树,{A}、{B}、{AR}、{BL}、{BR},且假定所有子树的高度为 H(或者你认为是 1 也可以)。如下图 即:A 的平衡粒子为 1,B 为 0,AR 无子树 现在:以 LL(左孩子的左子树) 插入,操作如下图: 此时:B 的子树高度为 H+1(已做 LL 操作),AR 不变,那 A 的平衡因子为 2 了。此时就成 A

five-five 1436

平衡二叉树(AVL树)旋转示例

示例:

Seasand-yyh的博客 2672

【高阶数据结构】平衡二叉树(AVL)的插入(4种图解旋转方法)

一篇文章彻底学会平衡二叉树的4种旋转方法,配图讲解超清晰!LL型插入,RR型插入,LR型插入和RL型插入

更新C/C++,数据结构与算法,计算机视觉,深度学习,目标检测 4219

AVL平衡二叉树及其4种旋转方式

1.AVL平衡二叉树:二叉树中每个节点的左子树和右子树高度之差的绝对值小于等于1。 2.平衡因子=左子树的高度-右子树的高度。AVL树的平衡因子只有-1,0,1。 3.右旋转 LL 旋转前特征: 1)节点a为不平衡的节点。 2)节点b和节点c为在高度较高的路径上,从a开始的接下来的两个节点。 3)y1,y2,y3和y4代表节点a,节点b,节点c的子节点或者子树。可以为null,...

醒醒 1767
上一篇: 二叉树与二叉查找树(附java代码实现)
下一篇: EventBus
MrMoving
博客等级 码龄10年 54粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值