深入探索C++中的AVL树

引言

在数据结构和算法的世界里,平衡二叉搜索树(Balanced Binary Search Tree, BST)是一种非常重要的数据结构。AVL树(Adelson-Velsky和Landis发明的树)就是平衡二叉搜索树的一种,它通过自平衡来维护其性质:任何节点的两个子树的高度差至多为1。这一特性使得AVL树在插入、删除和查找操作中都能保持相对稳定的性能。

一、AVL树的基本概念

AVL树是一种自平衡的二叉搜索树,它的每个节点都包含四个属性:键值、左子树指针、右子树指针和高度。高度是从该节点到其任一叶子节点的最长路径上边的数量。

二、AVL树的性质

  1. 二叉搜索树性质:对于任意节点N,其左子树上所有节点的键值都小于N的键值,而右子树上所有节点的键值都大于N的键值。
  2. 平衡性质:对于任意节点N,其左子树和右子树的高度差至多为1。

三、AVL树的旋转操作

当在AVL树中插入或删除节点时,可能会破坏其平衡性质。为了恢复平衡,我们需要进行旋转操作。旋转操作包括四种情况:右旋转(RR)、左旋转(LL)、左右旋转(LR)和右左旋转(RL)。

  1. 右旋转(RR):当某个节点的右子树的高度比左子树高2时,需要进行右旋转。
  2. 左旋转(LL):当某个节点的左子树的高度比右子树高2时,需要进行左旋转。
  3. 左右旋转(LR):当某个节点的左子树的右子树高度过高时,需要先进行左旋转,再进行右旋转。
  4. 右左旋转(RL):当某个节点的右子树的左子树高度过高时,需要先进行右旋转,再进行左旋转。

四、C++实现AVL树

在C++中,我们可以使用类和结构体来实现AVL树。以下是一个简化的AVL树节点结构定义和旋转操作的伪代码实现。

template<class T>
struct AVLTreeNode
{AVLTreeNode(const T& data = T()): _pLeft(nullptr), _pRight(nullptr), _pParent(nullptr), _data(data), _bf(0){}AVLTreeNode<T>* _pLeft;AVLTreeNode<T>* _pRight;AVLTreeNode<T>* _pParent;T _data;int _bf;   // 节点的平衡因子
};// AVL: 二叉搜索树 + 平衡因子的限制
template<class T>
class AVLTree
{typedef AVLTreeNode<T> Node;
public:AVLTree(): _pRoot(nullptr){}// 在AVL树中插入值为data的节点bool Insert(const T& data);
private:// 右单旋void RotateR(Node* pParent);// /// 左单旋void RotateL(Node* pParent);// '\'// 右左双旋void RotateRL(Node* pParent);//  >// 左右双旋void RotateLR(Node* pParent);//  <private:Node* _pRoot;
};

 1增加

bool Insert(const T& data){Node* newnode = new Node(data);if (_pRoot == nullptr){_pRoot = newnode;return true;}else{Node* parent = nullptr;Node* cur = _pRoot;while (cur){if (cur->_data < data){parent = cur;cur = cur->_pRight;}else if (cur->_data > data){parent = cur;cur = cur->_pLeft;}else{return false;}}if (parent->_data < data){parent->_pRight = newnode;}else{parent->_pLeft = newnode;}newnode->_pParent = parent;//更新平衡因子cur = newnode;while (parent){if (cur == parent->_pLeft){parent->_bf++;}else{parent->_bf--;}if (parent->_bf == 0){break;}else if (parent->_bf == 1 || parent->_bf == -1){cur = parent;parent = parent->_pParent;}else if (parent->_bf == 2 || parent->_bf == -2){if (parent->_bf == 2 && cur->_bf == 1){RotateR(parent);}else if (parent->_bf == -2 && cur->_bf == -1){RotateL(parent);}else if (parent->_bf == 2 && cur->_bf == -1){RotateLR(parent);}else{RotateRL(parent);}break;}else{assert(false);}}return true;}}

2右旋转

// 右单旋void RotateR(Node* pParent)//  /{Node* pchild = pParent->_pLeft;Node* pchildr = pchild->_pRight;Node* grandfather = pParent->_pParent;if (pchildr){pchildr->_pParent = pParent;}pParent->_pLeft = pchildr;pParent->_pParent = pchild;pchild->_pRight = pParent;if (pParent == _pRoot){_pRoot = pchild;pchild->_pParent = nullptr;}else{if (grandfather->_pLeft == pParent){grandfather->_pLeft = pchild;}else{grandfather->_pRight = pchild;}pchild->_pParent = grandfather;}pParent->_bf = pchild->_bf = 0;}

3.右左双旋

	// 右左双旋void RotateRL(Node* pParent)//  >{Node* pchild = pParent->_pRight;Node* pchildl = pchild->_pLeft;int bf = pchildl->_bf;RotateR(pchild);RotateL(pParent);pchildl->_bf = 0;if (bf == 1){pParent->_bf = 0;pchild->_bf = -1;}else if (bf == -1){pchild->_bf = 0;pParent->_bf = 1;}else{pParent->_bf = pchild->_bf = 0;}}

五、AVL树的应用

AVL树在需要频繁进行插入、删除和查找操作的场景中非常有用。例如,在数据库索引、文件系统的目录树等地方,AVL树都能提供高效的数据访问能力。

六、总结

AVL树作为一种平衡二叉搜索树,在维护其平衡性质的同时,也保证了高效的查找、插入和删除操作。通过旋转操作,AVL树能够在插入或删除节点后迅速恢复其平衡状态。在C++中,我们可以使用类和结构体来方便地实现AVL树,并将其应用到各种需要高效数据访问的场景中。

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

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

相关文章

支付宝推出NFC(近场通信)碰一碰支付功能

近日&#xff0c;支付宝推出NFC&#xff08;近场通信&#xff09;碰一碰支付功能&#xff0c;支持iPhone、安卓手机。NFC支付早已不是新事物&#xff0c;从二维码支付重回NFC支付&#xff0c;支付宝能撬动市场吗&#xff1f; 根据网友反馈&#xff0c;目前支付宝正在上海静安大…

node版本过高出现ERR_OSSL_EVP_UNSUPPORTED错误

错误原因&#xff1a; 新版本的nodejs使用的openssl和旧版本不同&#xff0c;导致出错 解决方法&#xff1a; 1.将node版本重新换回16.x 2 windows 下 在package.json文件下添加set NODE_OPTIONS--openssl-legacy-provider && "scripts": {"dev"…

车辆轨迹预测系列 (二):常见数据集介绍

车辆轨迹预测系列 (二)&#xff1a;常见数据集介绍 文章目录 车辆轨迹预测系列 (二)&#xff1a;常见数据集介绍1、NuScenes (2020)&#xff1a;1、下载2、说明 2、Waymo Open Dataset (2020)&#xff1a;1、介绍2、概述3、下载4、教程5、参考 3、Lyft Level 5 (2020)&#xff…

如何把期末成绩发给家长?

期末的脚步越来越近&#xff0c;又到了头疼成绩怎么群发给家长的时候了&#xff0c;别担心&#xff0c;期末成绩群发秘籍来帮忙&#xff0c;让我们一起完成这项任务&#xff01; 1. 邮件VS短信 首先得选个合适的沟通方式。邮件正式&#xff0c;适合详细说明&#xff1b;短信快…

数据仓库的实际应用示例-广告投放平台为例

数据仓库的数据分层通常包括以下几层&#xff1a; ODS层&#xff1a;存放原始数据&#xff0c;如日志数据和结构化数据。DWD层&#xff1a;进行数据清洗、脱敏、维度退化和格式转换。DWS层&#xff1a;用于宽表聚合值和主题加工。ADS层&#xff1a;面向业务定制的应用数据层。…

一个自定义流程的平台

脚本语言使用的是C#&#xff0c;当用户发布一个新的流程时&#xff0c;会把C#的脚本编译成dll&#xff0c;然后添加到微服务中&#xff0c;因为有了硬编译&#xff0c;所以执行速度是非常快的。逻辑脚本支持调试&#xff0c;可以断点和逐行调试。平台提供了调试工具&#xff0c…

DevEco鸿蒙开发请求网络交互设置

首先&#xff0c;在鸿蒙项目下config.json中找到module项&#xff0c;在里面填写"reqPermissions": [{"name": "ohos.permission.INTERNET"}] 在页面对应js文件内&#xff0c;填写import fetch from system.fetch;。 GET和POST区别 GET将表单数…

人工智能--搭建人工神经网络

欢迎来到 Papicatch的博客 文章目录 &#x1f349;引言 &#x1f349;神经元与感知器 &#x1f348;神经元&#xff08;Neuron&#xff09; &#x1f348;感知器 &#x1f349;损失函数与梯度下降算法 &#x1f348;损失函数 &#x1f348;梯度下降算法 &#x1f349;…

如何解决跨境传输常见的安全及效率问题?

在当今全球化的商业版图中&#xff0c;企业为了拓展国际市场和增强竞争力&#xff0c;跨境传输数据已成为一项不可或缺的业务活动。合格的数据跨境传输方案&#xff0c;应考虑以下要素&#xff1a; 法律合规性&#xff1a;确保方案符合所有相关国家的数据保护法律和国际法规&am…

ffmpeg音视频开发从入门到精通——ffmpeg下载编译与安装

音视频领域学习ffmpeg的重要性 音视频领域中ffmpeg的广泛应用&#xff0c;包括直播、短视频、网络视频、实时互动和视频监控等领域。掌握FM和音视频技术可以获得更好的薪酬。 学习建议音视频学习建议与实战应用 音视频处理机制的学习&#xff0c;需要勤加练习&#xff0c;带…

永磁同步电机驱动死区补偿

1 死区效应及补偿 1. 1 死区效应 在本文的电机控制嵌入式系统中,逆变器为三 相电压型桥式逆变电路,如图 1 所示。 在理想状态 下,上桥臂和下桥臂的控制信号满足互补通断原则, 即上桥臂开通时,下桥臂关断,反之亦然。 而在实际 应用中,开关管的通断需要一定的开通时…

使用GPT/文心实现诗词作画

在教育领域中&#xff0c;古诗词一直是培养学生文化素养和审美能力的重要载体。选择合适的古诗词进行学习和欣赏&#xff0c;不仅能够增强他们的语言表达能力&#xff0c;还能促进他们对中国传统文化的理解和热爱。本文将结合AI技术&#xff0c;将古诗词转换为图画。 1、选择适…

板凳--------第60章 SOCKET:服务器设计

60.1 迭代型和并发型服务器 1016 1.迭代型&#xff1a; 服务器每次只处理一个客户端&#xff0c;只有当完全处理完一个客户端的请求后才会去处理下一个客户端。只适用于快速处理客户端请求的场景&#xff0c;因为每个客户端都必须等待&#xff0c;直到前面所有的客户端都处理完…

mongosh常用命令详解及如何开启MongoDB身份验证

目录 Mongosh常用命令介绍 连接到MongoDB实例 基本命令 查看当前数据库 切换数据库 查看所有数据库 查看当前数据库中的集合 CRUD操作 插入文档 查询文档 更新文档 删除文档 替换文档 索引操作 创建索引 查看索引 删除索引 聚合操作 数据库管理 创建用户 …

安卓Context上下文

目录 前言一、Context简介二、Application Context2.1 Application Context的创建过程2.2 Application Context的获取过程 三、Activity的Context创建过程四、Service的Context创建过程 前言 Context也就是上下文对象&#xff0c;是Android较为常用的类&#xff0c;但是对于Co…

网络虚拟化考题

vrrp讲过吗&#xff1f;&#xff1f;&#xff1f; d 每一层都是什么设备啊 abcd 为啥流量不可控不可视 c是啥意思 讲过吗 abc aNET网络虚拟化是啥啊 为啥&#xff1f;&#xff1f; 啥是CDN&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;

奔驰EQS SUV升级原厂主动式氛围灯效果展示

以下是一篇关于奔驰 EQs 升级原厂主动氛围灯案例的宣传文案&#xff1a; 在汽车科技不断演进的今天&#xff0c;我们自豪地为您呈现奔驰 EQs 升级原厂主动氛围灯的精彩案例。 奔驰 EQs&#xff0c;作为豪华电动汽车的典范&#xff0c;其卓越品质与高端性能有目共睹。而此次升…

充电学习—6、电量计FuelGauge

电量计功能&#xff1a; 检测电池 计量电量 电量计首要工作&#xff1a; 计算电池的剩余容量、充满时容量、电量百分比 电量百分比 剩余容量 / 充满时容量 * 100% SOC RM / FCC * 100% 典型的一个电池包框架&#xff1a; 包含电芯、电量计IC、保护IC、充放电MOSFET、保险丝…

TrueNAS系统在ARM平台上的移植

随着家庭及中小型企业对存储和共享需求的日益增长&#xff0c;高效、可靠的文件存储系统成为支撑各类应用的关键。 在众多存储系统中&#xff0c;TrueNAS以其卓越的数据完整性与可靠性、简洁高效的应用程序部署和管理、灵活的虚拟化应用添加能力&#xff0c;以及出色的可用性&a…

【SpringBoot】SpringBoot:打造现代化微服务架构

文章目录 引言微服务架构概述什么是微服务架构微服务的优势 使用SpringBoot构建微服务创建SpringBoot微服务项目示例&#xff1a;创建订单服务 配置数据库创建实体类和Repository创建服务层和控制器 微服务间通信使用RestTemplate进行同步通信示例&#xff1a;调用用户服务 使用…