C++AVL树(一)详解

文章目录

  • AVL树
    • 概念
    • AVL树的插入
    • 平衡因子的更新
    • 旋转的规则
      • 左单旋
      • 右单旋
        • 抽象的情况
        • h==0
        • h==1
        • h== 2
        • h == 3

AVL树

概念

  • AVL树是一棵平衡二叉查找树,AVL树是空树,保证左右子树都是AVL树,AVL树要求高度差的绝对值不超过1,因为最好情况是1,比如4个节点高度差最好是1,2个也是1,3个节点最好是0
  • 任何子树-左右子树高度差的绝对值都是1
  • 这样AVL树就接近完全二叉树了,高度为logN,增删查改的效率就为logN
  • 任何节点的平衡因子:右子树-左子树的高度,0/-1/1,有了平衡因子就更容易控制AVL树是否平衡,但AVL树并不是必须要平衡因子

AVL树的插入

  1. 按二叉搜索树的规则进行插入
  2. 新增节点后会影响祖先节点的高度,也就是祖先节点的平衡因子,所以更新从新增节点到根节点路径上的平衡因子,实际最坏情况要跟新到根,也可能根新到中间就停止了
  3. 更新平衡因子中没有出现问题,插入结束
  4. 不平衡子树要进行旋转,旋转的本质是调平衡,进而降低子树的高度,不会再影响上一层,则插入结束

平衡因子的更新

更新规则:

  • 平衡因子 = 右子树的高度 - 左子树的高度
  • 只有子树的高度变化才会影响当前节点的平衡因子
  • 插入新节点,插入在左子树,parent节点平衡因子减减,插入在右子树,parent节点平衡因子加加
  • parent所在子树的高度的变化决定了是否继续向上更新
  • 高的那边才会影响平衡因子

更新的停止条件:

  1. 更新后平衡因子是1或者-1,那么更新前更新中平衡因子是0->-1,0->1,说明更新前parent子树两边一样高,更新后一边高一边低,符合平衡的要求,但是高度增加了1,高度的增加会影响parent节点的平衡因子,所以要继续向上更新
  2. 更新后parent平衡因子是0,更新中parent的平衡因子变化为-1->0,1->0,更新前parent的子树一边高一边低,更新后parent子树一样高,不会影响parent的平衡因子,所以停止更新
  3. 更新后parent平衡因子是2或-2-1->-2,1->2,更新前parent的子树一边高一边低,更新后,增加节点到了高的那边,高的那边更高了,所以高的那边破坏了平衡,需要旋转处理
  4. 旋转的目标:把parent的子树旋转平衡;降低parent子树的高度,恢复到插入之前的高度。插入之前是平衡的。
  5. 结束的3个情况:旋转后,插入结束;平衡因子是0;平衡因子是-1/1,但是更新到根节点都是-1/1也就结束了
    在这里插入图片描述

旋转的规则

  1. 保证旋转前和旋转后都是搜索树
  2. 让旋转的树从不满足平衡到满足平衡,其次还会降低旋转树的高度来满足平衡因子
    旋转分为四种:左单旋/右单旋/左右双旋/右左双旋

左单旋

左单旋:右边的树比左边的树高
左单旋和右单旋类似就不多做说明了
在这里插入图片描述

右单旋

右单旋:左边的树比右边的树高
a,b,c的高度都是h
h >= 0,a,b,c都是搜索二叉树,只是把它抽象出来了

抽象的情况
  1. 往右旋,5变为根,10变为5的右节点,b变为10的左节点
    在这里插入图片描述
h==0

在这里插入图片描述

h==1

在这里插入图片描述

h== 2

在这里插入图片描述

h == 3

在这里插入图片描述

#pragma once
#include<iostream>using namespace std;// 节点的结构
// 加了一个parent,为了找到父节点的父节点,从而往上走
template<class K,class V>
struct AVLTreeNode
{// 需要parent指针pair<K, V> _kv;AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;int _bf;// 平衡因子AVLTreeNode(const pair<K, V>& kv):_kv(kv),_left(nullptr),_right(nullptr),_parent(nullptr),_bf(0)// 刚插入的节点平衡因子都是0{}
};// 树的结构
template<class K,class V>
class AVLTree
{typedef AVLTreeNode<K, V> Node;
public:bool insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_kv.first < kv.first){parent = cur;cur = cur->_right;}else if (cur->_kv.first > kv.first){parent = cur;cur = cur->_left;}else{// 不冗余return false;}}// 链接父节点cur = new Node(kv);if (parent->_kv.first < kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent;// 更新平衡因子// 控制平衡while (parent){if (parent->_left == cur)parent->_bf--;else if (parent->_right == cur)parent->_bf++;if (parent->_bf == 0){break;}eles if (parent->_bf == -1 || parent->_bf == 1){cur = parent;parent = parent->_parent;}else if (parent->_bf == 2 || parent->_bf == -2){// 旋转break;}else{// 逻辑错误,之前就不是AVL树assert(false);}}return true;}
private:Node* _root = nullptr;
};

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

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

相关文章

JAVA与数据结构-线性表

目录 一.线性表的概念 二.线性表的关系及分类 三.数组与顺序表 四.链表 1.静态链表(链表的的数组底层实现&#xff09; 2.循环链表 3.双向链表 五.栈 1.栈的概念 2.栈的底层实现 3.共享空间栈 4.逆波兰表达式&#xff08;后缀表达式&#xff09; 5.栈与递归 六.…

AI绘画:从灵感到杰作的奇幻之旅(3/10)

AI 绘画&#xff1a;新时代的艺术创作浪潮 在数字化时代的浪潮下&#xff0c;AI 绘画已成为艺术领域中一颗耀眼的新星&#xff0c;掀起了一场前所未有的创作革命。只需在相关工具中输入简单的文字描述&#xff0c;或者上传一张参考图片&#xff0c;就能迅速生成令人惊叹的艺术…

【C语言系列】深入理解指针(3)

深入理解指针&#xff08;3&#xff09; 一、字符指针变量二、数组指针变量2.1数组指针变量是什么&#xff1f;2.2数组指针变量怎么初始化&#xff1f; 三、二维数组传参的本质四、函数指针变量4.1函数指针变量的创建4.2函数指针变量的使用4.3两段有趣的代码4.4 typedef关键字 …

广东某海水取排水管线工程边坡自动化监测

1. 项目简介 广东廉江核电项目田螺岭厂址位于廉江市车板镇北约4km处&#xff0c;地理位置为东经10948’28.88“北纬2134’01.55”&#xff0c;东距廉江市约48km&#xff0c;东南距湛江市约 65km&#xff0c;厂址西南距离北部湾约4.5km。广东廉江核电项目一期工程海水取排水管线…

Qt基础项目篇——Qt版Word字处理软件

一、核心功能 本软件为多文档型程序&#xff0c;界面是标准的 Windows 主从窗口 拥有&#xff1a;主菜单、工具栏、文档显示区 和 状态栏。 所要实现的东西&#xff0c;均在下图了。 开发该软件&#xff0c;主要分为下面三个阶段 1&#xff09;界面设计开发 多窗口 MDI 程序…

神经网络梯度爆炸的原因及解决方案

在深度学习中&#xff0c;梯度爆炸&#xff08;gradient exploding&#xff09;是一种常见的训练问题&#xff0c;尤其是在深层神经网络中。梯度爆炸指的是在反向传播过程中&#xff0c;梯度值呈指数级增长&#xff0c;导致网络权重的大幅更新&#xff0c;从而使得网络变得不稳…

deap系统重构,再新增一个新的因子,年化39.1%,卡玛提升至2.76(附python代码)

原创内容第776篇&#xff0c;专注量化投资、个人成长与财富自由。 本周核心工作之一&#xff0c;deap因子挖掘&#xff1a; Deap牛刀小试&#xff0c;挖掘出长期年化29.2%的轮动因子 deap时间序列函数补充&#xff0c;挖掘出年化39.12%的轮动因子&#xff0c;卡玛比率2.52 …

计算机图形学:实验二 三维模型读取与控制

一、程序功能设计 通过键盘和鼠标结合实现了对三维牛模型的变换控制&#xff0c;可以灵活调整旋转的轴、方向、速度以及暂停或复位三维牛模型状态。 动画启动和暂停&#xff1a; 按键&#xff1a;鼠标左键&#xff08;启动&#xff09;&#xff0c;鼠标右键&#xff08;暂停…

最新-CentOS 7 基于1 Panel面板安装 JumpServer 堡垒机

CentOS 7 基于1 Panel面板安装 JumpServer 堡垒机 一、前言二、设备要求三、环境要求四、安装4.1 环境安装4.2 JumpServer安装4.3 访问JumpServerWeb端&#xff0c;进行登录 五、登录Web控制台 一、前言 JumpServer是广受欢迎的开源堡垒机。运维必备神器&#xff01;JumpServe…

WordPress果果对象存储插件

将网站上的图片等静态资源文件上传至七牛云对象存储&#xff0c;可以减轻服务器文件存储压力&#xff0c;提升静态文件访问速度&#xff0c;从而加速网站访问速度。 支持&#xff1a;阿里云对象存储、华为云对象存储、百度云对象存储、腾讯云对象存储、七牛云对象存储。 下载…

ChatGPT大模型极简应用开发-CH2-深入了解 GPT-4 和 ChatGPT 的 API

文章目录 2.1 基本概念2.2 OpenAI API 提供的可用模型2.3 在 OpenAI Playground 中使用 GPT模型2.4 开始使用 OpenAI Python 库2.4.1 OpenAI 访问权限和 API 密钥2.4.2 Hello World 示例程序 2.5 使用 GPT-4 和 ChatGPT2.5.1 ChatCompletion 端点的输入选项2.5.2 ChatCompletio…

war包 | Docker部署flowable-ui

文章目录 引言I war包部署flowable-ui下载war包配置Tomcat访问 flowable-uiII Docker启动flowable-ui并修改配置Docker启动flowable-ui修改配置访问Flowable UI界面。III 知识扩展加速源docker run -i -t -d 参数引言 Flowable 支持 BPMN 2.0 行业标准,同时提供了一些 Flowab…

Qt Creator 15.0.0如何更换主题和字体

1.打开Qt Creator 15.0.0 (Community)&#xff0c; 2.点击编辑栏3.点击Preferences... 4.修改主题&#xff0c;点击环境&#xff0c;修改Theme:栏 5.修改字体大小&#xff0c;点击文本编辑器&#xff0c;修改字号栏。&#xff0c;修改Theme:栏

【2025小年源码免费送】

&#x1f496;学习知识需费心&#xff0c; &#x1f4d5;整理归纳更费神。 &#x1f389;源码免费人人喜&#xff0c; &#x1f525;码农福利等你领&#xff01; &#x1f496;山高路远坑又深&#xff0c; &#x1f4d5;大军纵横任驰奔&#xff0c; &#x1f389;谁敢横刀立马行…

python学opencv|读取图像(四十一 )使用cv2.add()函数实现各个像素点BGR叠加

【1】引言 前序已经学习了直接在画布上使用掩模&#xff0c;会获得彩色图像的多种叠加效果&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;四十&#xff09;掩模&#xff1a;三通道图像的局部覆盖-CSDN博客 这时候如果更进一步&#xff0c;直接…

【面试总结】FFN(前馈神经网络)在Transformer模型中先升维再降维的原因

FFN&#xff08;前馈神经网络&#xff09;在Transformer模型中先升维再降维的设计具有多方面的重要原因&#xff0c;以下是对这些原因的总结&#xff1a; 1.目标与动机 高维映射空间&#xff1a;FFN的设计目的是通过一系列线性变换来拟合一个高维的映射空间&#xff0c;而不仅…

生成模型:生成对抗网络-GAN

1.原理 1.1 博弈关系 1.1.1 对抗训练 GAN的生成原理依赖于生成器和判别器的博弈 生成器试图生成以假乱真的样本。判别器试图区分真假样本。 这种独特的机制使GAN在图像生成、文本生成等领域表现出色。 具有表现为: 生成器 (Generator, G) 生成器的目标是从一个随机噪声&…

MongoDB基本操作

一、实验目的 1. 熟悉MongoDB的基本操作&#xff0c;包括CRUD&#xff08;增加、读取、更新、删除&#xff09;。 2. 理解MongoDB的文档型数据库特性和Shell的使用。 3. 培养学生通过命令行操作数据库的能力。 4. 强化数据库操作的实际应用能力。 二、实验环境准备 1.…

微透镜阵列精准全检,白光干涉3D自动量测方案提效70%

广泛应用的微透镜阵列 微透镜是一种常见的微光学元件&#xff0c;通过设计微透镜&#xff0c;可对入射光进行扩散、光束整形、光线均分、光学聚焦、集成成像等调制&#xff0c;进而实现许多传统光学元器件难以实现的特殊功能。 微透镜阵列&#xff08;Microlens Array&#x…

AIGC视频生成模型:ByteDance的PixelDance模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍ByteDance的视频生成模型PixelDance&#xff0c;论文于2023年11月发布&#xff0c;模型上线于2024年9月&#xff0c;同时期上线的模型还有Seaweed&…