C++ AVL 树底层原理与实现

一、AVL 树的概念
AVL 树是一种高度平衡的平衡二叉树,相比于搜索二叉树,它的特点在于左右子树都为 AVL 树且树的高度差的绝对值不超过 1。
这里我们会引入一个新的概念叫做平衡因子。平衡因子也就是左右子树的高度差,我们可以通过平衡因子方便我们后续去观察和控制树是否平衡。

二、AVL 树的性质
AVL 树主要有三大性质:
- 每棵树的左右子树都是 AVL 树。
- 左子树和右子树的高度之差的绝对值不超过 1。
- 每个节点都会有一个平衡因子,且任何一个节点的平衡因子都为 1、0、-1。
三、AVL 树的实现
1. 树的基本结构
AVL 树的结点包含了左右节点的指针以及父亲节点的指针,同时还有 key、value 以及代表树平衡的平衡因子。
template <class K, class V>
struct AVLTreeNode {
pair<K, V> _kv;
AVLTreeNode<K, V>* _left;
AVLTreeNode<K, V>* _right;
AVLTreeNode<K, V>* _parent; // 平衡因子
int _bf;
AVLTreeNode(const pair<K, V>& kv) : _kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr), _bf(0) {}
};
2. 树的插入
树的插入按照搜索二叉树的规则进行插入。插入节点后更新平衡因子,如果没有违反规则 (即没有导致节点的平衡因子变成 2/-2),则插入结束;如果违反规则,则树会不平衡,需要进行旋转操作。
平衡因子的更新规则:
- 平衡因子 = 右子树高度 - 左子树高度。
- 只有子树高度的变化才会影响当前节点的平衡因子。
- 插入节点后会增加数的高度,若新增节点在 parent 的右子树,则 parent 的平衡因子 ++,相反在 parent 的左子树时,则平衡因子 --。
每更新完一个节点的平衡因子都需要进行以下判断:
- 如果 parent 的平衡因子等于 1/-1 时,说明 parent 原先的平衡因子为 0,插入节点后左子树或右子树的高度增加了,说明还需要向上更新平衡因子。








