2.5-数据结构:AVL树

news/2025/2/8 3:59:15/

2.5-AVL树

🌲 定义与性质

AVL树(Adelson-Velsky and Landis Tree)是最早发明的自平衡二叉搜索树,通过维护平衡因子确保树的高度始终为 O(log N)。其核心特性为:

  • 平衡因子:任意节点的左右子树高度差绝对值不超过 1
  • 旋转操作:通过四种旋转操作(左旋、右旋、左右旋、右左旋)动态调整平衡

⚖️ 平衡因子

每个节点的平衡因子计算公式:

平衡因子 = 右子树高度 - 左子树高度

平衡因子范围:[-1, 0, 1]

🔄 旋转操作类型

旋转类型触发条件示意图
左旋右子树右节点导致失衡→ 右侧超重拉平
右旋左子树左节点导致失衡← 左侧超重拉平
左右旋左子树右节点导致失衡↙ 先左旋再右旋
右左旋右子树左节点导致失衡↘ 先右旋再左旋

🖥️ 核心代码实现(C++)

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;// 定义AVL树节点结构
template<class K, class V>
struct AVLTreeNode {AVLTreeNode<K, V>* _left;  // 左子节点指针AVLTreeNode<K, V>* _right; // 右子节点指针AVLTreeNode<K, V>* _parent; // 父节点指针pair<K, V> _kv;  // 键值对int _bf; // balance factor 平衡因子// 构造函数,初始化节点AVLTreeNode(const pair<K, V>& kv): _left(nullptr), _right(nullptr), _parent(nullptr), _kv(kv), _bf(0) {}
};// 定义AVL树类
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->_left;} else if (cur->_kv.first < kv.first) {parent = cur;cur = cur->_right;} else {return false;}}cur = new Node(kv);// 插入新节点if (parent->_kv.first > kv.first) {parent->_left = cur;} else if (parent->_kv.first < kv.first) {parent->_right = cur;}cur->_parent = parent;// 更新平衡因子while (parent) {if (cur == parent->_right) {parent->_bf++;} else {parent->_bf--;}if (parent->_bf == 1 || parent->_bf == -1) {parent = parent->_parent;cur = cur->_parent;} else if (parent->_bf == 0) {break;} else if (parent->_bf == 2 || parent->_bf == -2) {// 旋转调整平衡if (parent->_bf == 2 && cur->_bf == 1) {RotateL(parent); // 左单旋} else if (parent->_bf == -2 && cur->_bf == -1) {RotateR(parent); // 右单旋} else if (parent->_bf == -2 && cur->_bf == 1) {RotateLR(parent); // 左右双旋} else if (parent->_bf == 2 && cur->_bf == -1) {RotateRL(parent); // 右左双旋}break;} else {assert(false);}}return true;}// 中序遍历AVL树void InOrder() {_InOrder(_root);cout << endl;}// 递归中序遍历辅助函数void _InOrder(Node* root) {if (root == nullptr) return;_InOrder(root->_left);cout << root->_kv.first << " ";_InOrder(root->_right);}// 判断AVL树是否平衡bool IsBalance() {return _IsBalance(_root);}private:Node* _root = nullptr;// 左单旋void RotateL(Node* parent) {Node* subR = parent->_right;Node* subRL = subR->_left;// 处理 subRL 与 parent 的连接parent->_right = subRL;if (subRL) {subRL->_parent = parent;}// 保存原父节点的父节点Node* pparent = parent->_parent;// 处理 subR 与 parent 的连接subR->_left = parent;parent->_parent = subR;// 处理 subR 与 pparent 的连接if (pparent == nullptr) {_root = subR;subR->_parent = nullptr;} else {if (pparent->_left == parent) {pparent->_left = subR;} else {pparent->_right = subR;}subR->_parent = pparent;}// 更新平衡因子parent->_bf = subR->_bf = 0;}// 右单旋void RotateR(Node* parent) {Node* subL = parent->_left;Node* subLR = subL->_right;// 处理 subLR 与 parent 的连接parent->_left = subLR;if (subLR) {subLR->_parent = parent;}// 保存原父节点的父节点Node* pparent = parent->_parent;// 处理 subL 与 parent 的连接subL->_right = parent;parent->_parent = subL;// 处理 subL 与 pparent 的连接if (pparent == nullptr) {_root = subL;subL->_parent = nullptr;} else {if (pparent->_left == parent) {pparent->_left = subL;} else {pparent->_right = subL;}subL->_parent = pparent;}// 更新平衡因子parent->_bf = subL->_bf = 0;}// 左右双旋void RotateLR(Node* parent) {Node* subL = parent->_left;Node* subLR = subL->_right;RotateL(parent->_left);RotateR(parent);int bf = subLR->_bf;// 根据subLR的平衡因子更新各节点平衡因子if (bf == 1) {parent->_bf = -1;subLR->_bf = 0;subL->_bf = -1;} else if (bf == -1) {parent->_bf = 1;subLR->_bf = 0;subL->_bf = -1;} else if (bf == 0) {parent->_bf = 0;subLR->_bf = 0;subL->_bf = 0;} else {assert(false);}}// 右左双旋void RotateRL(Node* parent) {Node* subR = parent->_right;Node* subRL = subR->_left;RotateR(parent->_right);RotateL(parent);int bf = subRL->_bf;// 根据subRL的平衡因子更新各节点平衡因子if (bf == 1) {parent->_bf = -1;subRL->_bf = 0;subR->_bf = 0;} else if (bf == -1) {parent->_bf = 0;subRL->_bf = 0;subR->_bf = 1;} else if (bf == 0) {parent->_bf = 0;subRL->_bf = 0;subR->_bf = 0;} else {assert(false);}}// 计算树的高度int _Height(Node* root) {if(root == nullptr) { return 0; }int leftH = _Height(root->_left);int rightH = _Height(root->_right);return leftH > rightH ? leftH + 1 : rightH + 1;}// 判断以root为根的子树是否平衡bool _IsBalance(Node* root) {if (root == nullptr) { return true; }return abs(_Height(root->_left) - _Height(root->_right)) < 2&& _IsBalance(root->_left) && _IsBalance(root->_right);}
};// 测试AVL树的插入和平衡性
void test_AVLTree() {int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };AVLTree<int, int> t1;for (auto e : a) {t1.Insert(make_pair(e, e));}t1.InOrder();cout << t1.IsBalance() << endl;
}

(尝试拿deepseek丰富前面的文案。)


http://www.ppmy.cn/news/1570230.html

相关文章

Spring Boot统一异常拦截实践指南

Spring Boot统一异常拦截实践指南 一、为什么需要统一异常处理 在Web应用开发中&#xff0c;异常处理是保证系统健壮性和用户体验的重要环节。传统开发模式中常见的痛点包括&#xff1a; 异常处理逻辑分散在各个Controller中错误响应格式不统一敏感异常信息直接暴露给客户端…

自然语言处理-词嵌入 (Word Embeddings)

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 词嵌入&#xff08;Word Embedding&#xff09;是一种将单词或短语映射到高维向量空间的技术&#xff0c;使其能够以数学方式表示单词之间的关系。词嵌入能够捕捉语义信息&#xff0c;使得相似的词在向量空间中具有…

配置Apache本地服务支持PHP8--易错点

配置Apache本地服务--易错点 到apache的bin目录下&#xff08;cmd)安装服务配置 apache 支持 php 参考: Windows 11 本地 php 开发环境搭建&#xff1a;PHP Apache MySQL VSCode 安装和环境配置 到apache的bin目录下&#xff08;cmd) 安装服务 httpd -k install -n Apache…

React Native 列表组件:FlashList、FlatList 及更多

在移动开发中&#xff0c;高效展示数据列表至关重要。作为 React Native 开发者&#xff0c;我们可以使用多种强大的工具来完成这一任务。无论是 ScrollView、SectionList 还是 FlatList&#xff0c;React Native 都提供了一系列用于数据展示的组件。 然而&#xff0c;随着数据…

二条命令,释放docker占用的存储空间

//删除空镜像 rootnode2:# docker images --quiet --filterdanglingtrue | xargs --no-run-if-empty docker rmi //清除缓存存储 rootnode2:# docker system prune WARNING! This will remove: all stopped containersall networks not used by at least one containerall da…

源路由 | 源路由网桥 / 生成树网桥

注&#xff1a;本文为 “源路由” 相关文章合辑。 未整理去重。 什么是源路由&#xff08;source routing&#xff09;&#xff1f; yzx99 于 2021-02-23 09:45:51 发布 考虑到一个网络节点 A 从路由器 R1 出发&#xff0c;可以经过两台路由器 R2、R3&#xff0c;到达相同的…

Unity 2D实战小游戏开发跳跳鸟 - 游戏开始UI界面及逻辑

有了游戏核心的计分逻辑之后,现在我们需要对游戏整体的流程进行控制和交互,这时需要实现游戏流程的UI界面,让用户可以通过UI的交互来开始游戏或者在跳跳鸟死亡时重新开始游戏等。 游戏开始界面 搭建一个游戏开始的UI界面,其结构如下所示。 首先创建一个空的游戏物体命名为…

【大数据技术】本机PyCharm远程连接虚拟机Python

本机PyCharm远程连接虚拟机Python 注意:本文需要使用PyCharm专业版。 pycharm-professional-2024.1.4VMware Workstation Pro 16CentOS-Stream-10-latest-x86_64-dvd1.iso写在前面 本文主要介绍如何使用本地PyCharm远程连接虚拟机,运行Python脚本,提高编程效率。 注意: …