平衡二叉树(AVL)平衡化旋转详解
一、平衡二叉树
1、为什么要引入平衡二叉树
平衡二叉树的全称是平衡二叉排序树,也称为AVL树,这是因为该树结构是由Adelson-Velskii和Landis在1963年提出的。AVL树是BST树的改进结构,使得平均查找长度得到了减少,进而提高了查找的效率。
BST树是一种查找效率较高的二叉树结构,但不是所有的BST树都能保证高效率的查找,其平均查找长度和树的深度有关。
例如有一组数据{5,4,3,2,1},在创建二叉排序树时,得到如下结果:
该树的深度是5,平均查找长度ASL=(1+2+3+4+5)/ 5 = 3。此时想查找元素3,需要比较3次才可找到,想查找元素2,需要比较4次才可以找到,查找效率很低。为了改进这个问题,Adelson-Velskii和Landis提出了改进的BST树,即平衡二叉排序树,结果如下:
该树的深度是3,平均查找长度ASL=(1+2x2+2x3)/ 5 = 2.2。此时想查找元素3,需要比较1次即可找到,想查找元素2,需要比较2次可以找到,查找效率得到了提高。
2、平衡因子与平衡二叉树
为了方便定义平衡二叉树,引入了平衡因子的概念。对某一个结点而言,该结点的平衡因子就是其左子树与右子树的深度差。
当BST树上的所有结点的平衡因子的取值为-1、 0 或者 1时,该树就是平衡二叉树。
下面的图中所示的二叉树均是平衡二叉树,这也是常见的平衡二叉树的基本型。
图(1)的平衡因子为1,(2)的平衡因子为0,(3)的平衡因子为-1。
在图(1)和(3)中,除了根结点,其它结点的平衡因子是0。
在图(2)中,结点8的平衡因子是-1,其它结点的平衡因子是0。
二、平衡化旋转
在创建BST树是,不一定都能保证是平衡二叉树,因此需要通过旋转操作将其转化为平衡二叉树。常见的旋转方法有LL型、RR型、LR型和RL型四种旋转。
2.1)LL型平衡化旋转
LL型旋转主要针对以下形式的BST树。
图(1)中的二叉树是平衡二叉树,其平衡因子为1。
在图(1)中插入新的结点6,得到图(2)所示的BST树,此时平衡因子是2,不满足平衡二叉树的条件,因此可以通过旋转的方法使其变成平衡二叉树。具体的做法是将二叉树以树根所在位置为旋转轴进行顺时针旋转,得到如图(3)所示的二叉树,即将左子树树根16提升为二叉树的树根,将结点16的右子树连接到原来树根结点25的左子树,以确保新得到的二叉树仍旧是二叉排序树,且平衡因子是0,因此就得到了一个平衡二叉树。
由于是在原来的平衡二叉树的左子树的左分支增加了新结点而导致了不平衡,所以该旋转方法就称为LL(Left-Left)型平衡化旋转,也称为右单旋转方法。
说明:如果在结点10的右子树插入新的结点,平衡化旋转方法也是相同的。
A)引入指针T和p,LL旋转过程如下图所示:
B)LL平衡化旋转算法如下:
p = T->L;
T->L = p->R;
p->R = T;
T = p;
平衡因子 = 0;
2.2)RR型平衡化旋转
RR型和LL型关于树根是对称的,如下图所示。
图(1)中的二叉树是平衡二叉树,其平衡因子为-1。
在图(1)中插入新的结点60,得到图(2)所示的BST树,此时平衡因子是-2,不满足平衡二叉树的条件,因此可以通过旋转的方法使其变成平衡二叉树。具体的做法是将二叉树以树根所在位置为旋转轴进行逆时针旋转,得到如图(3)所示的二叉树,即将右子树树根40提升为二叉树的树根,将结点40的左子树连接到原来树根结点25的右子树,以确保新得到的二叉树仍旧是二叉排序树,且平衡因子是0,因此就得到了一个平衡二叉树。
由于是在原来的平衡二叉树的右子树的右分支增加了新结点而导致了不平衡,所以该旋转方法就称为RR(Right-Right)型平衡化旋转。
说明:如果在结点50的左子树插入新的结点,平衡化旋转方法也是相同的。
A)引入指针T和p,RR旋转过程如下图所示:
B)RR平衡化旋转算法如下:
p = T->R;
T->R = p->L;
p->L = T;
T = p;
平衡因子 = 0;
2.3)LR型平衡化旋转
LR型平衡化旋转相对于LL型比较麻烦,涉及到两次旋转。第一次旋转是将LR型转化成LL型,第二次旋转则同LL型平衡化旋转相同。
如下图所示,假设有图(1)中所示的平衡二叉树,其平衡因子为1,现插入元素22,得到图(2)中所示的二叉树,此时该二叉树的平衡因子为2,不是平衡二叉树。为了提高查找效率,需要进行平衡化旋转,首先以左子树树根16为旋转轴,逆时针旋转一次,得到图(3)所示的二叉树,平衡因子为2,此时该二叉树和LL型相同,因此绕树根顺时针旋转即可得到图(4)所示的平衡二叉树,平衡因子为0.
该旋转方法由于是在左子树的有分支插入新的结点导致失衡,因此称为LR(Left-Right)型平衡化旋转。
A)引入指针T、p和q,LR旋转过程如下图所示:
B)LR平衡化旋转算法如下:
p = T->L;
q = p->R;
q->L = p;
p->R = NULL;
T->L = q->R;
q->R = T;
T = q;
平衡因子 = 0;
说明:如果在结点20的左子树插入新的结点,平衡化旋转方法如下:
2.4)RL型平衡化旋转
LR型平衡化旋转用到两次旋转。第一次旋转是将RL型转化成RR型,第二次旋转则同R型平衡化旋转相同。
如下图所示,假设有图(1)中所示的平衡二叉树,其平衡因子为-1,现插入元素28,得到图(2)中所示的二叉树,此时该二叉树的平衡因子为-2,不是平衡二叉树。为了提高查找效率,需要进行平衡化旋转,首先以右子树树根40为旋转轴,顺时针旋转一次,得到图(3)所示的二叉树,平衡因子为-2,此时该二叉树和RR型相同,因此绕树根逆时针旋转即可得到图(4)所示的平衡二叉树,平衡因子为0.
该旋转方法由于是在左子树的有分支插入新的结点导致失衡,因此称为RL(Right-Left)型平衡化旋转。
A)引入指针T、p和q,RL旋转过程如下图所示:
B)RL平衡化旋转算法如下:
p = T->R;
q = p->L;
q->R = p;
p->L = NULL;
T->R = q->L;
q->L = T;
T = q;
平衡因子 = 0;
说明:如果在结点30的右子树插入新的结点,平衡化旋转方法如下:
注:平衡化旋转方法是不唯一的,上述只是给出了其中的一类旋转方法。
平衡二叉树(AVL)平衡化旋转详解相关推荐
- AVL树平衡旋转详解
AVL树平衡旋转详解 概述 AVL树又叫做平衡二叉树.前言部分我也有说到,AVL树的前提是二叉排序树(BST或叫做二叉查找树).由于在生成BST树的过程中可能会出现线型树结构,比如插入的顺序是:1, ...
- UIDeviceOrientation 和 UIInterfaceOrientation 设备旋转的用法 (实例) 和 IOS6屏幕旋转详解
1. UIDeviceOrientation 和 UIInterfaceOrientation 设备旋转的用法 (实例) 博客分类: IOS / Objective-C UIDeviceOrienta ...
- Unity史上最全旋转详解(Rotate,rotation,localEulerAngles,localRotation,万向节锁)
Unity史上最全旋转详解 前言 旋转的方法Rotate以及五种重载参数的超级详细理解 Rotate(float xAngle, float yAngle, float zAngle); Unity绕 ...
- AVL平衡二叉树旋转详解
AVL(平衡二叉树) AVL定义 左子树和右子树的高度之差的绝对值不超过1,高度之差也叫做平衡因子(Balance Factor),简称BF 左右子树也都是平衡二叉树 当一个节点没有左子树时,左子树高 ...
- 【数据结构】平衡二叉树的调整(RR LL LR RL)旋转详解讲解
平衡二叉树的调整 旋转的命名规则 RR旋转(右单旋) LL旋转(左单旋) LR旋转(左右旋转) RL旋转(右左旋转) 旋转的命名规则 如图初始插入节点Nov后,Mar节点的平衡因子(左右两个子树的 ...
- 数据结构:关于AVL树的平衡旋转详解
前言 本文是基于你已经有一定的二叉排序树知识.如果你还是小白,可以参考我之前的博客:<数据结构:二叉搜索树(BST)的基本操作>.所以,在本文中不会再出现关于BST树的基本知识. 版权说明 ...
- (王道408考研数据结构)第五章树-第四节2:平衡二叉树(AVL)及其旋转
文章目录 一:AVL树基本概念 二:AVL树实现原理 (1)构建AVL树 (2)构建演示 (3)旋转方法 A:右单旋转调整(插入到较高左子树左侧) B:左单旋转调整(插入到较高右子树右侧) C:先左后 ...
- IOS6屏幕旋转详解(自动旋转、手动旋转、兼容IOS6之前系统)
转自 http://blog.csdn.net/zzfsuiye/article/details/8251060 概述: 在iOS6之前的版本中,通常使用 shouldAutorotateToInte ...
- 【OpenCV】图像旋转详解,边缘用黑色填充
项目要用到图像旋转,OpenCV里面居然没有专门封装好的函数,只好自己写了.根据<learnning OpenCV>发现效果不是很理想,旋转后图像大小不变,可是图像却被裁减了. 例子如下: ...
最新文章
- Beep()之我迷糊了……
- GitHub最最最火的开源爬虫工具箱,一爬就取
- 思路拓展,如果是用2D的方式去做切割
- flask 操作mysql的两种方式-sqlalchemy操作
- 拉普拉斯矩阵(Laplace Matrix)与瑞利熵(Rayleigh quotient)
- 【常用】截取相机图片截图功能
- 怎么把mysql表里的时间往后推移_Mysql实战45讲笔记:2、更新语句的执行以及日志...
- mybatis log4j 在日志中打印sql_SpringBoot整合MyBatis+详细打印执行SQL语句
- row_number() over使用方法
- 深入理解Flex布局以及计算
- 【HDOJ2222】Keywords Search(AC自动机)
- Linux用户登录日志查询
- origin 复制与数据转置
- 债券收益率预测模型_股债收益率模型看A股估值 股债收益率模型(EYBY)是一个经典的股市估值模型,其基本思想是将“股票收益率”(EY)与“债券收益率”(BY)进行对比... - 雪球...
- linux mariadb,linux配置mariaDB
- UnboundLocalError local variable torch referenced before assignment
- P1538 迎春舞会之数字舞蹈
- linux管理账户是,Linux管理账户
- Python抢票神器
- MATLAB裁剪视频(裁剪固定区域)