AVL树的插入案例:
几点说明
- 每个node有一个平衡因子,左子树插入节点,平衡因子-1,右子树插入节点,平衡因子+1
- 右单旋条件:该节点(parent)平衡因子-2,左儿子(subL)平衡因子为-1,则Rrevole(parent),旋转后两个平衡因子置为0;
- 左单旋条件:该节点(parent)平衡因子2,右儿子(subR)平衡因子为1,则Lrevole(parent),旋转后两个平衡因子置为0;
- 右左双旋条件:该节点(parent)平衡因子2,右儿子(subR)平衡因子为-1,则先右单选右儿子Rrevole(subR),再左单旋Lrevole(parent),这两个单选的过程中平衡因子暂不处理,统一交由RLrevole处理;
- 左右双旋条件:该节点(parent)平衡因子-2,左儿子(subL)平衡因子为1,则先单旋左儿子Lrevole(subL),再右单旋Rrevole(parent),平衡因子处理同上。
左单旋和右单旋要处理平衡因子的情况:
void Rrevole(node* parent) {
node* subL = parent->_left;
node* pparent = parent->parent;
node* subLR = subL->_right;
if (parent->_bf * subL->_bf == 2) {
parent->_bf = 0;
subL->_bf = 0;
}
subL->parent = pparent;
parent->parent = subL;
parent->_left = subLR;
subL->_right = parent;
if (subLR) {
subLR->parent = parent;
}
if (pparent == nullptr) {
_root = subL;
return;
}
if (pparent->_left == parent) {
pparent->_left = subL;
}
else if (pparent->_right == parent) {
pparent->_right = subL;
}
}
void Lrevole(node* parent) {
node* subR = parent->_right;
node* pparent = parent->parent;
node* subRL = subR->_left;
if (parent->_bf * subR->_bf == 2) {
parent->_bf = 0;
subR->_bf = 0;
}
subR->parent = pparent;
parent->parent = subR;
parent->_right = subRL;
subR->_left = parent;
if (subRL) {
subRL->parent = parent;
}
if (pparent == nullptr) {
_root = subR;
return;
}
if (pparent->_left == parent) {
pparent->_left = subR;
}
else if (pparent->_right == parent) {
pparent->_right = subR;
}
}
左右双旋以及右左双旋的平衡因子分别有三种情况:
void RLrevole(node* parent) {
node* subR = parent->_right;
node* subRL = subR->_left;
Rrevole(subR);
Lrevole(parent);
if (subRL->_bf == 1) {
parent->_bf = -1;
subR->_bf = 0;
subRL->_bf = 0;
}
else if (subRL->_bf == -1) {
parent->_bf = 0;
subR->_bf = 1;
subRL->_bf = 0;
}
else if (subRL->_bf == 0) {
parent->_bf = 0;
subR->_bf = 0;
subRL->_bf = 0;
}
}
void LRrevole(node* parent) {
node* subL = parent->_left;
node* subLR = subL->_right;
Lrevole(subL);
Rrevole(parent);
if (subLR->_bf == 1) {
parent->_bf = 0;
subL->_bf = -1;
subLR->_bf = 0;
}
else if (subLR->_bf == -1) {
parent->_bf = 1;
subL->_bf = 0;
subLR->_bf = 0;
}
else if (subLR->_bf == 0) {
parent->_bf = 0;
subL->_bf = 0;
subLR->_bf = 0;
}
}
总插入代码与实际案例:
#include <iostream>
#include <utility>
using namespace std;
template <class K, class V>
struct AVLTreeNode {
AVLTreeNode* parent;
AVLTreeNode* _left;
AVLTreeNode* _right;
pair<K, V> _kv;
int _bf;
AVLTreeNode(pair<K, V> kv)
: parent(nullptr)
, _left(nullptr)
, _right(nullptr)
, _kv(kv)
, _bf(0)
{
}
};
template<class K, class V>
class AVLTree {
public:
typedef struct AVLTreeNode<K, V> node;
AVLTree(int size = 0, node* root = nullptr)
:_size(size)
,_root(root)
{
}
void Rrevole(node* parent) {
node* subL = parent->_left;
node* pparent = parent->parent;
node* subLR = subL->_right;
if (parent->_bf * subL->_bf == 2) {
parent->_bf = 0;
subL->_bf = 0;
}
subL->parent = pparent;
parent->parent = subL;
parent->_left = subLR;
subL->_right = parent;
if (subLR) {
subLR->parent = parent;
}
if (pparent == nullptr) {
_root = subL;
return;
}
if (pparent->_left == parent) {
pparent->_left = subL;
}
else if (pparent->_right == parent) {
pparent->_right = subL;
}
}
void Lrevole(node* parent) {
node* subR = parent->_right;
node* pparent = parent->parent;
node* subRL = subR->_left;
if (parent->_bf * subR->_bf == 2) {
parent->_bf = 0;
subR->_bf = 0;
}
subR->parent = pparent;
parent->parent = subR;
parent->_right = subRL;
subR->_left = parent;
if (subRL) {
subRL->parent = parent;
}
if (pparent == nullptr) {
_root = subR;
return;
}
if (pparent->_left == parent) {
pparent->_left = subR;
}
else if (pparent->_right == parent) {
pparent->_right = subR;
}
}
void RLrevole(node* parent) {
node* subR = parent->_right;
node* subRL = subR->_left;
Rrevole(subR);
Lrevole(parent);
if (subRL->_bf == 1) {
parent->_bf = -1;
subR->_bf = 0;
subRL->_bf = 0;
}
else if (subRL->_bf == -1) {
parent->_bf = 0;
subR->_bf = 1;
subRL->_bf = 0;
}
else if (subRL->_bf == 0) {
parent->_bf = 0;
subR->_bf = 0;
subRL->_bf = 0;
}
}
void LRrevole(node* parent) {
node* subL = parent->_left;
node* subLR = subL->_right;
Lrevole(subL);
Rrevole(parent);
if (subLR->_bf == 1) {
parent->_bf = 0;
subL->_bf = -1;
subLR->_bf = 0;
}
else if (subLR->_bf == -1) {
parent->_bf = 1;
subL->_bf = 0;
subLR->_bf = 0;
}
else if (subLR->_bf == 0) {
parent->_bf = 0;
subL->_bf = 0;
subLR->_bf = 0;
}
}
bool insert(const pair<K, V>& kv) {
if (!_root) {
_root = new node(kv);
return true;
}
node* cur = _root;
node* parent = nullptr;
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;
}
}
node* newnode = new node(kv);
newnode->parent = parent;
if (parent->_kv.first < kv.first) {
parent->_right = newnode;
parent->_bf++;
}
else if (parent->_kv.first > kv.first) {
parent->_left = newnode;
parent->_bf--;
}
while (parent) {
node* pparent = parent->parent;
if (parent->_bf == 0) {
break;
}
else if (parent->_bf == -1 || parent->_bf == 1) {
if (pparent == nullptr) {
break;
}
else if (parent == pparent->_left) {
pparent->_bf--;
}
else if (parent == pparent->_right) {
pparent->_bf++;
}
parent = pparent;
}
else if (parent->_bf == -2 || parent->_bf == 2) {
if (parent->_bf == -2) {
if (parent->_left->_bf == -1) {
Rrevole(parent);
}
else if (parent->_left->_bf == 1) {
LRrevole(parent);
}
}
else if (parent->_bf == 2) {
if (parent->_right->_bf == 1) {
Lrevole(parent);
}
else if (parent->_right->_bf == -1) {
RLrevole(parent);
}
}
break;
}
}
}
private:
int _size;
node* _root;
};
typedef pair<int, int>PII;
int main() {
AVLTree<int, int> AVL(100);
AVL.insert(PII(914, 1));
AVL.insert(PII(1167, 2));
AVL.insert(PII(8279, 3));
AVL.insert(PII(9923, 4));
AVL.insert(PII(328, 5));
AVL.insert(PII(3439, 6));
AVL.insert(PII(3640, 7));
AVL.insert(PII(6103, 8));
AVL.insert(PII(6104, 9));
return 0;
}