AVL树详解(附带旋转步骤图,手把手带你上分)
创始人
2024-04-06 08:45:32

文章目录

  • 👍 AVL树的概念先了解一下
  • 😁AVL树节点的定义
    • 😊AVL树插入节点
  • 🤞AVL树为什么要旋转
  • 😍AVL树的四种旋转
    • 左单旋
    • 右单旋
    • 左右双旋
    • 右左双旋
  • ❤️结语


关于AVL树的讲解

👍 AVL树的概念先了解一下


  • 它的左右子树都是AVL树
  • 左右子树高度之差(简称平衡因子)的绝对值不超过1 (-1/0/1)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MlyXcMxn-1668154168392)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6905b990ac694ebab9a03d2a44f0c8a7~tplv-k3u1fbpfcp-watermark.image?)]

  • 如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在 O(log2n)O(log_2 n)O(log2​n),搜索时间复杂度O(log2nlog_2 nlog2​n)。

😁AVL树节点的定义


//AVL 树的节点
template
struct AVLTreeNode
{pair _kv;AVLTreeNode* _left;AVLTreeNode* _right;AVLTreeNode* _parent;//左右子数的高度差int _bf;AVLTreeNode(const pair& kv):_kv(kv),_left(nullptr),_right(nullptr),_parent(nullptr), _bf(0){}
};

😊AVL树插入节点

bool Insert(const pair& kv){// 1、搜索树的规则插入// 2、看是否违反平衡规则,如果违反就需要处理:旋转if (_root == nullptr){_root = new Node(kv);_root->_bf = 0;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 (cur == parent->_right){parent->_bf++;}else{parent->_bf--;}// 是否继续更新?if (parent->_bf == 0)  // 1 or -1  -》 0  插入节点填上矮的那边{// 高度不变,更新结束break;}else if (parent->_bf == 1 || parent->_bf == -1)// 0  -》 1 或 -1  插入节点导致一边变高了{// 子树的高度变了,继续更新祖先cur = cur->_parent;parent = parent->_parent;}else if (parent->_bf == 2 || parent->_bf == -2)// -1 or 1  -》 2 或 -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{// 插入之前AVL就存在不平衡子树,|平衡因子| >= 2的节点assert(false);}}return true;}

🤞AVL树为什么要旋转


当一个树左右高度差绝对值大于1 的时候就要进行旋转

这是一个简单的示范:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fmbnuLF2-1668154168393)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c39f842b8f704cccba14a58aa95ab270~tplv-k3u1fbpfcp-watermark.image?)]


😍AVL树的四种旋转

左单旋

图片演示(我自己纯手画):

在这里插入图片描述

代码:

void RotateL(Node* parent)//左单旋{Node* SubR = parent->_right;Node* SubRL = SubR->_left;parent->_right = SubRL;if (SubRL){SubRL->_parent = parent;}Node* ppNode = parent->_parent;SubR->_left = parent;parent->_parent = SubR;if (_root == parent){_root = SubR;_root->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = SubR;}else{ppNode->_right = SubR;}SubR->_parent = ppNode;}//旋转结束更新平衡因子parent->_bf = 0;SubR->_bf = 0;}

右单旋

图片演示(我纯手画)

在这里插入图片描述

代码:

void RotateR(Node* parent)//右单旋{Node* SubL = parent->_left;Node* SubLR = SubL->_right;parent->_left = SubLR;if (SubLR){SubLR->_parent = parent;}Node* ppNode = parent->_parent;SubL->_right = parent;parent->_parent = SubL;if (_root == parent){_root = SubL;_root->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = SubL;}else{ppNode->_right = SubL;}SubL->_parent = ppNode;}//旋转结束更新平衡因子parent->_bf = 0;SubL->_bf = 0;}

左右双旋

图片演示(我纯手画):

在这里插入图片描述

parent节点平衡因子和subL节点的平衡因子都与subLR有关

subLRparentsubL
000
10-1
-110

代码:

void RotateLR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;int bf = subLR->_bf;RotateL(parent->_left);RotateR(parent);// 更新平衡因子if (bf == 0){parent->_bf = 0;subL->_bf = 0;subLR->_bf = 0;}else if (bf == 1){parent->_bf = 0;subL->_bf = -1;subLR->_bf = 0;}else if (bf == -1){parent->_bf = 1;subL->_bf = 0;subLR->_bf = 0;}else{// subLR->_bf旋转前就有问题assert(false);}}

右左双旋

图片演示(我自己纯手画):

在这里插入图片描述
e?)]

parent节点平衡因子和subR节点的平衡因子都与subRL有关

subRLparentsubR
000
1-10
-101

代码:

void RotateRL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;int bf = subRL->_bf;RotateR(parent->_right);RotateL(parent);if (bf == 0){subRL->_bf = 0;parent->_bf = 0;subR->_bf = 0;}else if (bf == 1){subRL->_bf = 0;parent->_bf = -1;subR->_bf = 0;}else if (bf == -1){subRL->_bf = 0;parent->_bf = 0;subR->_bf = 1;}else{// subLR->_bf旋转前就有问题assert(false);}}

❤️结语

一起加油
请添加图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...