AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。AVL树得名于它的发明者G. M. Adelson-Velsky和E. M. Landis,他们在1962年的论文《An algorithm for the organization of information》中发表了它。

AVL树还是一个搜索二叉树,只不过因为普通的搜索二叉树有可能变成单只树,这样就使查找效率非常的低。我们就给普通的搜索二叉树增加了一个平衡因子来使AVL左右子树的高度差的绝对值不超过1
- template<class K,class V>
- struct AVLTreeNode
- {
- AVLTreeNode<K, V>* _left;
- AVLTreeNode<K, V>* _right;
- AVLTreeNode<K, V>* _parent;
- pair<K, V> _kv; // 存储的键对
- int _bf; // balance factor
-
- AVLTreeNode(const pair<K, V>& kv)
- :_left(nullptr)
- , _right(nullptr)
- , _parent(nullptr)
- , _kv(kv)
- , _bf(0)
- {}
- };
-
- template<class K, class V>
- class AVLTree
- {
- typedef AVLTreeNode<K, V> Node;
- public:
- bool Insert(const pair<K, V>& kv);
- bool IsBalance();
- void InOrder();
- void Height();
-
- private:
- void RotateL(Node* parent); //左旋转
- void RotateR(Node* parent); //右旋转
- void RotateRL(Node* parent); //右左旋转
- void RotateLR(Node* parent); //左右旋转
- bool _IsBalance(Node* root);
- void _InOrder(Node* root);
- int _Height(Node* root);
-
-
- Node* _root = nullptr;
- };
- template<class K, class V>
- bool AVLTree<K, V>::Insert(const pair<K, V>& kv)
- {
- if (_root == nullptr)
- {
- _root = new Node(kv);
- return true;
- }
-
- 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);
- if (parent->_kv.first > kv.first)
- {
- parent->_left = cur;
- }
- else
- {
- parent->_right = cur;
- }
- cur->_parent = parent;
-
- // 更新平衡因子
- while (parent)
- {
- if (cur == parent->_right)
- {
- parent->_bf++;
- }
- else
- {
- parent->_bf--;
- }
-
- if (parent->_bf == 1 || parent->_bf == -1)
- {
- // 继续更新
- parent = parent->_parent;
- cur = cur->_parent;
- }
- else if (parent->_bf == 0)
- {
- break;
- }
- else if (parent->_bf == 2 || parent->_bf == -2)
- {
- // 需要旋转处理 -- 1、让这颗子树平衡 2、降低这颗子树的高度
- if (parent->_bf == 2 && cur->_bf == 1)
- {
- RotateL(parent);
- }
- else if (parent->_bf == -2 && cur->_bf == -1)
- {
- RotateR(parent);
- }
- else if (parent->_bf == -2 && cur->_bf == 1)
- {
- RotateLR(parent);
- }
- else if (parent->_bf == 2 && cur->_bf == -1)
- {
- RotateRL(parent);
- }
- else
- {
- assert(false);
- }
-
- break;
- }
- else
- {
- assert(false);
- }
- }
-
- return true;
- }

- template<class K, class V>
- void AVLTree<K, V>::RotateL(Node* parent)
- {
- Node* subR = parent->_right;
- Node* subRL = subR->_left;
-
- parent->_right = subRL;
- subR->_left = parent;
-
- Node* parentParent = parent->_parent;
-
- parent->_parent = subR;
- if (subRL)
- subRL->_parent = parent;
-
- if (_root == parent)
- {
- _root = subR;
- subR->_parent = nullptr;
- }
- else
- {
- if (parentParent->_left == parent)
- {
- parentParent->_left = subR;
- }
- else
- {
- parentParent->_right = subR;
- }
-
- subR->_parent = parentParent;
- }
-
- parent->_bf = subR->_bf = 0;
- }

60为parent,30为subL,b为subLR
- template<class K, class V>
- void AVLTree<K, V>::RotateR(Node* parent)
- {
- Node* subL = parent->_left;
- Node* subLR = subL->_right;
-
- parent->_left = subLR;
- if (subLR)
- subLR->_parent = parent;
-
- Node* parentParent = parent->_parent;
-
- subL->_right = parent;
- parent->_parent = subL;
-
- if (_root == parent)
- {
- _root = subL;
- subL->_parent = nullptr;
- }
- else
- {
- if (parentParent->_left == parent)
- {
- parentParent->_left = subL;
- }
- else
- {
- parentParent->_right = subL;
- }
-
- subL->_parent = parentParent;
- }
-
- subL->_bf = parent->_bf = 0;
- }

先对30进行左单旋,先对90右单旋
- template<class K, class V>
- void AVLTree<K, V>::RotateLR(Node* parent)
- {
- Node* subL = parent->_left;
- Node* subLR = subL->_right;
- int bf = subLR->_bf;
-
- RotateL(parent->_left);
- RotateR(parent);
-
- if (bf == 0)
- {
- parent->_bf = subL->_bf = subLR->_bf = 0;
- }
- else if (bf == -1)
- {
- parent->_bf = 1;
- subLR->_bf = 0;
- subL->_bf = 0;
- }
- else if (bf == 1)
- {
- parent->_bf = 0;
- subLR->_bf = 0;
- subL->_bf = -1;
- }
- else
- {
- assert(false);
- }
- }

先对90进行右单旋,先对30左单旋
- template<class K, class V>
- void AVLTree<K, V>::RotateRL(Node* parent)
- {
- Node* subR = parent->_right;
- Node* subRL = subR->_left;
- int bf = subRL->_bf;
-
- RotateR(parent->_right);
- RotateL(parent);
-
- if (bf == 0)
- {
- // subRL自己就是新增
- parent->_bf = subR->_bf = subRL->_bf = 0;
- }
- else if (bf == -1)
- {
- // subRL的左子树新增
- parent->_bf = 0;
- subRL->_bf = 0;
- subR->_bf = 1;
- }
- else if (bf == 1)
- {
- // subRL的右子树新增
- parent->_bf = -1;
- subRL->_bf = 0;
- subR->_bf = 0;
- }
- else
- {
- assert(false);
- }
- }
AVL树是带有平衡条件的二叉查找树,一般是用平衡因子差值判断是否平衡并通过旋转来实现平衡,左右子树树高不超过1,和红黑树相比,它是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1)。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入删除次数比较少,但查找多的情况。
- #include<assert.h>
-
- template<class K,class V>
- struct AVLTreeNode
- {
- AVLTreeNode<K, V>* _left;
- AVLTreeNode<K, V>* _right;
- AVLTreeNode<K, V>* _parent;
- pair<K, V> _kv; // 存储的键对
- int _bf; // balance factor
-
- AVLTreeNode(const pair<K, V>& kv)
- :_left(nullptr)
- , _right(nullptr)
- , _parent(nullptr)
- , _kv(kv)
- , _bf(0)
- {}
- };
-
- template<class K, class V>
- class AVLTree
- {
- typedef AVLTreeNode<K, V> Node;
- public:
- bool Insert(const pair<K, V>& kv);
- bool IsBalance();
- void InOrder();
- void Height();
-
- private:
- void RotateL(Node* parent); //左旋转
- void RotateR(Node* parent); //右旋转
- void RotateRL(Node* parent); //右左旋转
- void RotateLR(Node* parent); //左右旋转
- bool _IsBalance(Node* root);
- void _InOrder(Node* root);
- int _Height(Node* root);
-
-
- Node* _root = nullptr;
- };
-
- template<class K, class V>
- bool AVLTree<K, V>::Insert(const pair<K, V>& kv)
- {
- if (_root == nullptr)
- {
- _root = new Node(kv);
- return true;
- }
-
- 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);
- if (parent->_kv.first > kv.first)
- {
- parent->_left = cur;
- }
- else
- {
- parent->_right = cur;
- }
- cur->_parent = parent;
-
- // 更新平衡因子
- while (parent)
- {
- if (cur == parent->_right)
- {
- parent->_bf++;
- }
- else
- {
- parent->_bf--;
- }
-
- if (parent->_bf == 1 || parent->_bf == -1)
- {
- // 继续更新
- parent = parent->_parent;
- cur = cur->_parent;
- }
- else if (parent->_bf == 0)
- {
- break;
- }
- else if (parent->_bf == 2 || parent->_bf == -2)
- {
- // 需要旋转处理 -- 1、让这颗子树平衡 2、降低这颗子树的高度
- if (parent->_bf == 2 && cur->_bf == 1)
- {
- RotateL(parent);
- }
- else if (parent->_bf == -2 && cur->_bf == -1)
- {
- RotateR(parent);
- }
- else if (parent->_bf == -2 && cur->_bf == 1)
- {
- RotateLR(parent);
- }
- else if (parent->_bf == 2 && cur->_bf == -1)
- {
- RotateRL(parent);
- }
- else
- {
- assert(false);
- }
-
- break;
- }
- else
- {
- assert(false);
- }
- }
-
- return true;
- }
-
- template<class K, class V>
- void AVLTree<K, V>::RotateL(Node* parent)
- {
- Node* subR = parent->_right;
- Node* subRL = subR->_left;
-
- parent->_right = subRL;
- subR->_left = parent;
-
- Node* parentParent = parent->_parent;
-
- parent->_parent = subR;
- if (subRL)
- subRL->_parent = parent;
-
- if (_root == parent)
- {
- _root = subR;
- subR->_parent = nullptr;
- }
- else
- {
- if (parentParent->_left == parent)
- {
- parentParent->_left = subR;
- }
- else
- {
- parentParent->_right = subR;
- }
-
- subR->_parent = parentParent;
- }
-
- parent->_bf = subR->_bf = 0;
- }
-
- template<class K, class V>
- void AVLTree<K, V>::RotateR(Node* parent)
- {
- Node* subL = parent->_left;
- Node* subLR = subL->_right;
-
- parent->_left = subLR;
- if (subLR)
- subLR->_parent = parent;
-
- Node* parentParent = parent->_parent;
-
- subL->_right = parent;
- parent->_parent = subL;
-
- if (_root == parent)
- {
- _root = subL;
- subL->_parent = nullptr;
- }
- else
- {
- if (parentParent->_left == parent)
- {
- parentParent->_left = subL;
- }
- else
- {
- parentParent->_right = subL;
- }
-
- subL->_parent = parentParent;
- }
-
- subL->_bf = parent->_bf = 0;
- }
-
- template<class K, class V>
- void AVLTree<K, V>::RotateRL(Node* parent)
- {
- Node* subR = parent->_right;
- Node* subRL = subR->_left;
- int bf = subRL->_bf;
-
- RotateR(parent->_right);
- RotateL(parent);
-
- if (bf == 0)
- {
- // subRL自己就是新增
- parent->_bf = subR->_bf = subRL->_bf = 0;
- }
- else if (bf == -1)
- {
- // subRL的左子树新增
- parent->_bf = 0;
- subRL->_bf = 0;
- subR->_bf = 1;
- }
- else if (bf == 1)
- {
- // subRL的右子树新增
- parent->_bf = -1;
- subRL->_bf = 0;
- subR->_bf = 0;
- }
- else
- {
- assert(false);
- }
- }
-
- template<class K, class V>
- void AVLTree<K, V>::RotateLR(Node* parent)
- {
- Node* subL = parent->_left;
- Node* subLR = subL->_right;
- int bf = subLR->_bf;
-
- RotateL(parent->_left);
- RotateR(parent);
-
- if (bf == 0)
- {
- parent->_bf = subL->_bf = subLR->_bf = 0;
- }
- else if (bf == -1)
- {
- parent->_bf = 1;
- subLR->_bf = 0;
- subL->_bf = 0;
- }
- else if (bf == 1)
- {
- parent->_bf = 0;
- subLR->_bf = 0;
- subL->_bf = -1;
- }
- else
- {
- assert(false);
- }
- }
-
- template<class K, class V>
- void AVLTree<K, V>::InOrder()
- {
- _InOrder(_root);
- cout << endl;
- }
-
- template<class K, class V>
- void AVLTree<K, V>::_InOrder(Node* root)
- {
- if (root == nullptr)
- return;
-
- _InOrder(root->_left);
- cout << root->_kv.first << " ";
- _InOrder(root->_right);
- }
-
- template<class K, class V>
- bool AVLTree<K, V>::IsBalance()
- {
- return _IsBalance(_root);
- }
-
- template<class K, class V>
- int AVLTree<K, V>::_Height(Node* root)
- {
- if (root == nullptr)
- return 0;
-
- int leftHeight = _Height(root->_left);
- int rightHeight = _Height(root->_right);
-
- return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
- }
-
- template<class K, class V>
- void AVLTree<K, V>::Height()
- {
- cout << _Height(_root) << endl;
- }
-
- template<class K, class V>
- bool AVLTree<K,V>::_IsBalance(Node* root)
- {
- if (root == nullptr)
- return true;
-
- int leftHeight = _Height(root->_left);
- int rightHeight = _Height(root->_right);
- if (rightHeight - leftHeight != root->_bf)
- {
- cout << root->_kv.first << "平衡因子异常" << endl;
- return false;
- }
-
- return abs(rightHeight - leftHeight) < 2
- && _IsBalance(root->_left)
- && _IsBalance(root->_right);
- }