AVL 树简介
AVL 树是一种自平衡的二叉查找树(BST),由 G.M. Adelson-Velsky 和 E.M. Landis 于 1962 年提出。它的核心特性是保证每个节点的左右子树高度差不超过 1,从而确保插入、删除和查找的时间复杂度始终维持在 O(log N)。
平衡因子定义
每个节点都有一个平衡因子(_bf),计算公式为:左子树高度 - 右子树高度。
- 若为 0,表示左右高度相等。
- 若为 1,表示左子树比右子树高 1。
- 若为 -1,表示右子树比左子树高 1。
一旦平衡因子的绝对值达到 2,树即失衡,需要通过旋转操作恢复平衡。
节点结构设计
在实现之前,我们需要定义节点结构。除了存储键值对 _kv 和左右指针外,还需要父指针 _parent 来辅助旋转时的指针调整,以及记录平衡因子 _bf。
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) {}
};
插入与平衡维护
插入操作遵循二叉查找树的规则,但关键在于插入后如何更新平衡因子并处理失衡情况。
1. 按 BST 规则插入
首先找到插入位置。如果树为空,直接设为根节点;否则沿路径比较大小,直到找到空位。插入新节点后,需更新其父节点的平衡因子。
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);
cur->_parent = parent;
if (parent->_kv.first < kv.first) {
parent->_right = cur;
} {
parent->_left = cur;
}




