数据结构与算法 – AVL树
AVL
树(得名于发明者G. M. Adelson-Velsky 和 E. M. Landis)本质上是一棵带有平衡条件的二叉搜索树。
AVL
树具有以下2
个性质:
- 左子树和右子树的深度之差的绝对值不超过
1
; - 左子树和右子树全都是
AVL
树。
其中为了度量左右子树的深度之差,我们引入平衡因子(BF)
的概念。
平衡因子: 某个节点的左子树的高度减去右子树的高度得到的差值。
对于一棵 AVL
树,里面的所有节点的平衡因子只能取值于-1、0、1
,否则,AVL
树将是不平衡的并且需要平衡调整。
1. AVL 树平衡调整
二叉树的平衡化有两大基础操作: 左旋(rotate left)和右旋(rotate right)。
-
左旋,即是逆时针旋转,以某个节点作为旋转点,其右子节点变为旋转节点的父节点,右子节点的左子节点变为旋转节点的右子节点,左子节点保持不变;
-
右旋,即是顺时针旋转,以某个节点作为旋转点,其左子节点变为旋转节点的父节点,左子节点的右子节点变为旋转节点的左子节点,右子节点保持不变。
这种旋转在整个平衡化过程中可能进行一次或多次,这两种操作都是从失去平衡的最小子树根节点开始的(即离插入节点最近且平衡因子超过1的祖节点)。
造成失衡一共有 4
种情况:LL型、LR型、RL型、RR型,如下图所示。
-
LL型
平衡调整:对节点C
右旋即可。 -
LR型
平衡调整:先对A
进行一次左旋再对C
进行一次右旋。 -
RL型
平衡调整:先对C
进行一次右旋再对A
进行一次左旋。 -
RR型
平衡调整:对节点A
左旋即可。
2. 模拟建 AVL 树
按照整数序列 {4,5,7,2,1,3,6} 依次插入AVL
树。
由于AVL
树必须保证左右子树平衡(左子树和右子树的深度之差的绝对值不超过1
),
所以在插入的时候很容易出现不平衡的情况,一旦这样,就需要进行旋转以求达到平衡。
正是由于这种严格的平衡条件,导致AVL
需要花大量时间在调整上,故AVL
树一般适用于查询场景, 而不适用于增删频繁的场景。
相关系列文章
- 数据结构与算法 -- B 树 与 B+ 树
- 数据结构与算法 -- 常见算法思想
- 数据结构与算法 -- Trie 树 与 AC 自动机
- 数据结构与算法 -- 单模式字符串匹配算法(BF、RK、KMP、BM)
- 数据结构与算法 -- 二分查找
- 数据结构与算法 -- 排序算法
- 数据结构与算法 -- 图(Graph)
- 数据结构与算法 -- 堆(Heap)
- 数据结构与算法 -- 红黑树(Red-Black Tree)
- 数据结构与算法 -- AVL树
- 数据结构与算法 -- 二叉树
- 数据结构与算法 -- 哈希算法
- 数据结构与算法 -- 散列表(Hash Table)
- 数据结构与算法 -- 跳表(Skip List)
- 数据结构与算法 -- 栈(Stack)与 队列(Queue)
- 数据结构与算法 -- 数组与链表
- 数据结构与算法 -- 复杂度分析