AVL平衡树

news2024/12/28 20:10:39

前置知识

平衡树

平衡树指的是任意节点的子树的高度差都小于等于 1 1 1 的二叉查找树。

因为他是平衡的,我们做树上的操作就可以降到 O ( l o g n ) O(log_n) O(logn) 的时间复杂度。

AVL平衡树

因为对于树有可能进行插入或删除操作,使得树有可能不平衡,甚至变成链,导致操作变成 O ( n ) O(n) O(n) 的时间复杂度。

所以我们需要对树进行一些操作,使得它变成平衡的。

这里有很多种,比如说 s p l a y , t r e a p , f h q t r e a p , A V L splay,treap,fhqtreap,AVL splay,treap,fhqtreap,AVL ,这里主要讲讲 A V L AVL AVL

因为我们需要插入或者删除一个节点,某个节点的平衡因子的绝对值小于等于 2 2 2 ,所以我们只需要把子树旋转一下就好了。(我们这里的平衡因子定义为左子树的高度减去右子树的高度)

然而旋转有四种情况。

我们先来看看旋转的基本操作。

旋转

基本操作

右旋(zig)

对于以 x x x 为根的子树,如下图。

在这里插入图片描述

我们将它右旋一下,则会变成下图。

在这里插入图片描述

本质上就是将 x x x 的左子树变成 y y y 的右子树, y y y 的右儿子变成 x x x ,其他不变。

代码实现如下:

void zig(int &r) {
    int t = tree[r].l;
    tree[r].l = tree[t].r, tree[t].r = r, updata(r), updata(t), r = t;//updata就是更新子树的大小和高度。
}

左旋(zag)

还是以 x x x 为根的子树。

在这里插入图片描述

左旋之后如下图。

在这里插入图片描述

本质上就是将 x x x 的右子树变成 z z z 的左子树,将 z z z 的左儿子变成 x x x ,其他不变。

代码实现如下:

void zag(int &r) {
    int t = tree[r].r;
    tree[r].r = tree[t].l, tree[t].l = r, updata(r), updata(t), r = t;
}

基本的两个操作就讲完了,我们来看看如何旋转。

旋转的分类

如果左右子树高度差的绝对值大于 1 1 1 ,则我们需要靠旋转来维护。

假设我们以 x x x 为根的子树的平衡因子的绝对值大于 1 1 1 ,则旋转分为一下四种情况。

  • x x x 的平衡因子为 2 2 2 x x x 的左子树的平衡因子为 1 1 1 ,则需要对 x x x 进行一次 z i g zig zig
  • x x x 的平衡因子为 2 2 2 x x x 的左子树的平衡因子为 − 1 -1 1 ,则需要先将 x x x 的左儿子进行一次 z a g zag zag ,在对 x x x 做一次 z i g zig zig
  • x x x 的平衡因子为 − 2 -2 2 x x x 的右子树的平衡因子为 − 1 -1 1 ,则需要对 x x x 进行一次 z a g zag zag
  • x x x 的平衡因子为 − 2 -2 2 x x x 的右子树的平衡因子为 1 1 1 ,则需要先将 x x x 的右儿子进行一次 z i g zig zig ,在对 x x x 做一次 z a g zag zag

经过这样旋转,以 x x x 为根的子树就又平衡了。

代码实现如下:

int BF(int r) { return tree[tree[r].l].h - tree[tree[r].r].h; }
void maintain(int &r) {
    updata(r);
    int fs = BF(r), fl;
    if (fs > 1) {
        fl = BF(tree[r].l);
        if (fl > 0)
            zig(r);
        else
            zag(tree[r].l), zig(r);
    }
    if (fs < -1) {
        fl = BF(tree[r].r);
        if (fl < 0)
            zag(r);
        else
            zig(tree[r].r), zag(r);
    }
}

因为平衡树也是二叉查找树,所以查询就跟二叉查找树一样,因为旋转操作不会改变树的 d f s dfs dfs 序。

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

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

相关文章

抓取HTTPS失败和乱码

第一步&#xff1a;电脑安装SSL证书 选择 “Help” -> “SSL Proxying” -> “Install Charles Root Certificate”&#xff0c;如果设置了安全防护&#xff0c;会ranging输入系统的帐号密码 这时开始安装charles证书&#xff0c;一路点击下一步即可 第二步&#xf…

【MySQL进阶教程】锁的详细介绍

前言 本文为 【MySQL进阶教程】锁 相关知识&#xff0c;下边将对锁的概述&#xff0c;全局锁&#xff08;包含全局锁的介绍&#xff0c;语法与特点&#xff09;&#xff0c;表级锁&#xff08;包含表级锁的介绍&#xff0c;表锁&#xff0c;元数据锁&#xff0c;意向锁&#xf…

第一封信|感觉孤独?找个借口联系

首发&#xff1a;https://bornforthis.cn/letter/2023/01.html 孤独不等于寂寞 你好&#xff0c;我是悦创。 这里是《悦创来信去无方向的信》&#xff0c;给你邮寄的第一封信&#xff0c;信的主题是“孤独 vs 寂寞”&#xff0c;很高兴你拆开此信。 一到冬季&#xff0c;情…

10条必备的markdown常用语法

10条必备的markdown常用语法markdown笔记写起来会比较方便&#xff0c;而且也方便复制&#xff0c;下面我总结一下常用的markdown常用语法可能不同的程序markdown语法不太一样&#xff0c;但是都差不多的1.标题一级标题、二级标题等等这个不多说了。最多支持六级标题## 内容1 …

鲲志说:向我跌宕起伏,喜忧参半的2022致敬!

今天是2022的倒数第二天&#xff0c;就着CSDN的活动正好为自己做一个年度总结&#xff0c;也确实需要做一个年度总结来正式和过去的一年道个别 回想这一年&#xff0c;确实经历了很多&#xff0c;寒冬裁员、千里相赴见双方父母、成功夺冠&#x1f411;。。。成年人的世界确实很…

Web3中文|2023加密圈开年首雷?美国当局调查Genesis母公司DCG

据彭博社周五报道&#xff0c;纽约联邦检察官和美国证券交易委员会&#xff08;SEC&#xff09;正在调查数字货币集团&#xff08;DCG&#xff09;在其借贷子公司Genesis的内部转账问题。 报道援引知情人士的话称&#xff0c;DCG已收到纽约东区检察官关于提供文件和面谈的要求…

ebpf中的percpu map的注意事项与剖析

1 背景 故事还要从一次翻车现场说起。 为了统计各个CPU上的系统调用数据按照cpu分别进行统计&#xff0c;我参考了kernel Documents中关于percpu map的一段原话&#xff1a; Values stored in BPF_MAP_TYPE_ARRAY can be accessed by multiple programs across different CPUs.…

python转C++格式学习笔记

我是主写python的&#xff0c;但是感觉算法上想精进的话&#xff0c;还是得用c写&#xff0c;所以笔记主要记录的是c与python不太一样的地方&#xff0c;听的是y总的算法基础课&#xff0c;结合y总的讲义&#xff0c;白框里面是自己的理解&#xff0c;大家取精华&#xff0c;去…

已解决pip使用阿里云镜像安装第三方模块失败

已解决&#xff08;pip使用阿里云镜像安装第三方模块失败&#xff09;ERROR: Could not find a version that satisfies the requirement xpinyin (from versions: none) ERROR: No matching distribution found for xpinyin WARNING: The repository located at mirrors.aliyu…

2023年,我们还需要一部游戏手机吗?

这世界上本没有路&#xff0c;走的人多了&#xff0c;也便成了路。可实际情况全都如此吗&#xff1f;眼下&#xff0c;游戏手机的路似有还无。2022年12月下旬&#xff0c;刚晋升为小米集团总裁的卢伟冰&#xff0c;在宣传自家的Redmi K60系列时&#xff0c;称“K60宇宙&#xf…

npm无法使用的坑及其解决

1.&#xff08;如果是第一次可以跳过这个步骤&#xff09;如果你是下载了nodejs的话,那么请以此删除一下的文件:(他们可能有也可能没有&#xff0c;但有的话把它们删除) C:\Program Files (x86)\nodejs C:\Program Files\nodejs C:\Users{User}\AppData\Roaming\npm&#xff08…

【强训】Day05

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、选择二、编程1. 统计回文:sparkles: 2. 连续最大和[dp]答案1. 选择2. 编程普通小孩也要热爱生活&#xff01; 一、选择 下面的程序 编译运行后&#xff0c;在屏幕上显示的结果是&#xff08;&#xff09; pub…

LWIP(二)——LWIP有3种编程接口,RAW、NETCONN和SOCKET

目录 1. RAW 2. NETCONN 3、SOCKET LWIP有3种编程接口&#xff0c;RAW、NETCONN和SOCKET。它们的易用性从左到右依次提高&#xff0c;而执行效率从左到右依次降低&#xff0c;用户可以根据实际情况&#xff0c;平衡利弊&#xff0c;选择合适的 API 进行网络应用程序的开发。…

性价比高的香港物理服务器怎么选用?

​  从事跨境业务&#xff0c;对于网络流量大且速度、安全网络要求高的企业&#xff0c;通常建议选用香港物理服务器。物理服务器以非共享方式租给一个特定的客户&#xff0c;比较满足一些企业的高要求。当然&#xff0c;在进行比较并选择性价比高的香港物理服务器时&#xf…

Flink 知识点整理及八股文问题<第二、三部分 Flink快速上手和部署>

本篇为Flink的第二、三部分&#xff0c;Flink快速上手和Flink部署&#xff0c;全篇参考自 尚硅谷2022版1.13系列 整个系列的目录如下&#xff1a; &#x1f49a;<一>Flink简介 &#x1f49a;<二>Flink快速上手 &#x1f49a;<三>Flink 部署 &#x1f49a;&l…

Revit标注墙偏移如何简便标注呢?万能标注?

一、Revit标注墙偏移如何简便标注呢? 1、如果墙定位线是核心层中心线&#xff0c;现在要标注墙偏移如何简便标注呢? 遇到上述问题大家可能想到的办法是用TAB键去选择墙的内外边缘。其实有更简便的方法&#xff0c;如图1所示。 红色框选部分是选项栏&#xff0c;当使用对齐尺寸…

JDBC高级——主键回显、批量插入、事务操作

自增主键回显 一般在插入数据时&#xff0c;设置主键为自增&#xff0c;然后我们就不用去维护这个主键值&#xff0c;其他的级联表可能以这个主键作为外键或参考&#xff0c;所以我们要拿到插入数据的主键值&#xff0c;这就是主键回显。 如何获取数据库自增的主键值&#xff…

自己写一个简单的工作流引擎V2

上一篇文中我们实现了顺序的工作流&#xff0c;对于多分支的工作流如下&#xff0c;该如何实现呢&#xff1f; 小明提交了一个申请单&#xff0c;然后经过经理审批&#xff0c;如果通过&#xff0c;发邮件通知&#xff0c;不通过&#xff0c;则打回重新填写申请单&#xff0c;…

计算机体系结构 | 函数栈帧 | 栈帧的创建与销毁讲解 | 篡改函数的返回地址

文章目录前言预备知识demo及其汇编代码汇编代码讲解返回值篡改&#xff08;111 ???&#xff09;前言 复习时遇到一些问题&#xff0c;可能是关于左值右值的概念理解不够透彻&#xff0c;于是转头去研究左值右值的问题&#xff0c;但是想要参透左右值&#xff0c;我又觉得需…

通信网络概论

一、通信网络概述 通信网络是一些设备、设施组成的集合&#xff0c;可以提供特定的服务&#xff0c;即可以实现位于任意地点的不同用户间信息的传递。 通信网络的基本问题&#xff1a;如何以尽可能低的成本有效地解决处于任何地理位置的任意两个用户之间即时信息传递问题&…