AVL树

二叉平衡树

二叉搜索树
二叉搜索树又称二叉排序树,它或者是一颗空树,或者是具有以下性质的二叉树:
(1):对于它的任意一个结点而言,若该结点的左子树不为空,则左子树上所有结点的值小于该结点的值.。
(1):对于它的任意一个结点而言,若该结点的右子树不为空,则右子树上所有结点的值大于该结点的值.。
即对于他的任意一个结点而言,该结点的左右子树也分别为二叉搜索树

二叉搜索树的查找
既然将其称之为二叉搜索树,因此这棵树最主要的作用是进行查询,而且其查询原理特别简单,具体如下:
若根节点不为空:
若根节点key == 查找key,返回true
若根节点key大于查找key,在其左子树查找
若根节点key小于查找key,在其右子树查找
若最终仍未找到,返回false

插入和删除操作,也都是建立在查找的基础之上的,理想情况下,二叉搜索树的查找时间复杂度为O(log(n)),但是,在最坏的情况下(对于任意一个节点,都只有左孩子或者右孩子的情况下),他的时间复杂度为O(n),进而导致插入和删除的时间复杂度也变为O(n)

为了解决上述问题,引入了平衡树的概念,平衡树是指任意结点,左右子树的高度差都小于等于 1 ,AVL 树就是一个二叉平衡搜索树

AVL树
由上述我们就知道,AVL树是在二叉搜索树的基础上要求,任意结点左右子树的高度差不超过 1,并将高度差命名为平衡因子(Balance Factor),二叉树的结点代码如下:

class Node {
	private K key;
	private V value;  // K-V模型带着value,纯key模型可以不带value

	Node<K,V> left;
	Node<K,V> right;

	int bf;  //平衡因子
	Node<K,V> parent; // 保存自己的双亲结点,如果是跟,则为null
}

我们具体讲AVL树插入的过程:
1.按照普通搜索树的方式进行插入,若 key 重复,则放弃插入
2.插入后依次往上修改平衡因子,修改的原则为:
如果插入的地方为该结点的左孩子,则平衡因子 - 1
如果插入的地方为该结点的右孩子,则平衡因子 + 1
因此,在插入前,AVL树的平衡因子的取值范围为 [ -1, 0, 1 ],插入后,因为平衡因子被修改,所以,平衡因子的取值范围变为 [ -2,-1, 0, 1 ,2],

如果被修复后,平衡因子为 0 ,则表示这棵树的高度插入前后未改变
在这里插入图片描述
因为该结点的的平衡因子为 0 ,,高度未改变,不会继续影响该结点的的父结点的平衡因子,所以插入过程结束,整棵树仍是AVL树

如果修改后平衡因子 == -1 / 1,则说明高度发生了变化,增加了 1
在这里插入图片描述
所以该结点的父节点的平衡因子也需要被调整
在这里插入图片描述
也就是说,只要平衡因子调节完的结果是 -1/1,则调整平衡因子的过程会向上蔓延

如果被修改后的平衡因子的值为 -2 或者 2 ,则说明AVL树的特征被改变了,那么我们就需要利用规则进行修复。在修复之前,任意时刻,一个AVL树最多只有一个结点的平衡因子不满足特征,修复子树的过程会保证这颗子树的高度不变,这样不至于影响到该子树父结点的平衡因子。
在这里插入图片描述
AVL树把破坏规则的情况称为失衡(失去平衡),失衡的情况分为 4 类;

1. 左左失衡: parent 的失衡是因为在 parent 的左孩子的左子树中插入导致的失衡,如下:

在这里插入图片描述
针对左左失衡的情况,只需要对parent(失衡的结点)进行右旋即可
在这里插入图片描述

2.左右失衡:parent 的失衡是因为在 parent 的左孩子的右子树中插入导致的失衡
在这里插入图片描述
针对左右失衡的情况,先对 cur 进行左旋,再对 parent 进行右旋
在这里插入图片描述
3.右右失衡:parent 的失衡是因为在 parent 的右孩子的右子树中插入导致的失衡
针对右右失衡的情况,与左左失衡类似,只需要对parent(失衡的结点)进行左旋即可

2.右左失衡:parent 的失衡是因为在 parent 的右孩子的左子树中插入导致的失衡
针对右左失衡的情况,先对 cur 进行右旋,再对 parent 进行左旋

AVL树性能分析
AVL树是一棵绝对平衡的二叉搜索树,其要求每个节点的左右子树高度差的绝对值都不超过1,这样可以保证查询时高效的时间复杂度,即O(log(n))。但是如果要对AVL树做一些结构修改的操作,性能非常低下,比如:插入时要维护其绝对平衡,旋转的次数比较多,更差的是在删除时,有可能一直要让旋转持续到根的位置。因此:如果需要一种查询高效且有序的数据结构,而且数据的个数为静态的(即不会改变),可以考虑AVL树,但一个结构经常修改,就不太适合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

运笔如飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值