AVL树的插入接口需要分多种情况讨论,
前提是依据插入后平衡因子的值来做调整:
1.平衡因子为0,结束调整;
2.平衡因子为正负1,继续向上调整,直到0;
3.平衡因子为正负2,此时还需要进一步讨论:
出现平衡因子±2比较复杂,需要针对每一种情况做出不同旋转:
3.1. pParent的平衡因子为2,说明pParent的右子树高,设pParent的右子树的根为pSubR
当pSubR的平衡因子为1时,执行左单旋
当pSubR的平衡因子为-1时,执行右左双旋
3.2. pParent的平衡因子为-2,说明pParent的左子树高,设pParent的左子树的根为pSubL
当pSubL的平衡因子为-1是,执行右单旋
当pSubL的平衡因子为1时,执行左右双旋
旋转完成后,原pParent为根的子树个高度降低,已经平衡,不需要再向上更新。
#include<iostream>
using namespace std;
template<class T>
//AVLTree节点
class AVLNode{
public:
//AVL数有3个节点指针,1个val,1个平衡因子
int _bf;
T _val;
AVLNode<T>* _partent;
AVLNode<T>* _left;
AVLNode<T>* _right;
AVLNode(const T& val = T())//类0值
:_bf(0)
, _val(val)
, _partent(nullptr)
, _left(nullptr)
, _right(nullptr)
{}
};
//AVLTree树
template<class T>
class AVLTree{
public:
typedef AVLNode<T> Node;
bool insert(const T& val){
//先判断是否为空树
if (_root == nullptr){
_root = new Node(val);
return true;
}
Node* node=_root;
Node* partent=nullptr;
while (node){
partent = node;
if (node->_val == val){
return false;
}
else if (node->_val > val){
node = node->_left;
}
else{
node = node->_right;
}
}
//此时node在空上,并且没有链接父节点
node = new Node(val);
//此时链接父节点
if (partent->_val>val){
partent->_left = node;
}
else{
partent->_right = node;
}
node->_partent = partent;
//开始调整bf
//从partent开始
while (partent){
//先对父节点bf进行增或减
if (partent->_left == node)
--partent->_bf;
else
++partent->_bf;
//根据调整后的bf操作
//bf==0,结束调整
//bf=+-1,继续向上更新
//bf=+-2,需要旋转
if (partent->_bf == 0){
break;
}
else if (partent->_bf == 1 || partent->_bf == -1){
node = partent;
partent = partent->_partent;
}
else if(abs(partent->_bf)==2){
if (node->_bf == -1 && partent->_bf == -2){
//需要右旋
RotateR(partent);
}
else if (node->_bf == 1 && partent->_bf == 2){
RotateL(partent);
}
else if (partent->_bf == 2 && node->_bf == -1){
Node* subRL = node->_left;
int bf = subRL->_bf;
RotateR(node);
RotateL(partent);
if (bf == 1){
partent->_bf = -1;
node->_bf = 0;
}
else if (bf == -1){
node->_bf = 1;
partent->_bf = 0;
}
}
else if (partent->_bf == -2 && node->_bf == 1){
Node* subLR = node->_right;
int bf = subLR->_bf;
RotateL(node);
RotateR(partent);
if (bf == 1){
partent->_bf = 0;
node->_bf = -1;
}
else if (bf == -1){
node->_bf = 0;
partent->_bf = 1;
}
}
break;
}
}
return true;
}
// partent subL
//subL -> partent
// subLR subLR
void RotateR(Node* partent){
Node* subL = partent->_left;
Node* subLR = subL->_right;
subL->_right = partent;
partent->_left = subLR;
if (subLR){
subLR->_partent = partent;
}
//调整上部节点
if (partent == _root){
_root = subL;
subL->_partent = nullptr;
}
else{
Node* pparent = partent->_partent;
if (pparent->_left == partent){
pparent->_left = subL;
}else{
pparent->_right = subL;
}
subL->_partent = pparent;
}
partent->_partent = subL;
subL->_bf = partent->_bf = 0;
}
//partent subR
// subR -> partent
// subRL subRL
void RotateL(Node* partent){
Node* subR = partent->_right;
Node* subRL = subR->_left;
subR->_left = partent;
partent->_right = subRL;
if (subRL){
subRL->_partent = partent;
}
partent->_partent = subR;
//调整上部节点
if (partent == _root){
_root = subR;
subR->_partent = nullptr;
}
else{
Node* pparent = partent->_partent;
if (pparent->_left == partent){
pparent->_left = subR;
}
else{
pparent->_right = subR;
}
subR->_partent = pparent;
}
subR->_bf = partent->_bf = 0;
}
void _inorder(Node* root){
if (root){
_inorder(root->_left);
cout << root->_val << " ";
_inorder(root->_right);
}
}
void inorder(){
return _inorder(_root);
}
//检查AVL是否正确
//查看节点长度
int Height(Node* root){
if (root == nullptr){
return 0;
}
int left = Height(root->_left);
int right = Height(root->_right);
return left > right ? left + 1 : right + 1;
}
bool _isbalance(Node* root){
if (root == nullptr){
return true;
}
int left = Height(root->_left);
int right = Height(root->_right);
if (right - left != root->_bf){
cout << root->_val <<":错误"<< endl;
return false;
}
return abs(root->_bf) < 2 && _isbalance(root->_left) && _isbalance(root->_right);
}
bool isbalance(){
return _isbalance(_root);
}
private:
//记得置空
AVLNode<T>* _root=nullptr;
};
void test(){
AVLTree<int> t;
t.insert(5);
t.insert(3);
t.insert(1);
t.insert(0);
t.insert(2);
t.insert(-1);
t.insert(5);
t.insert(1);
t.inorder();
cout << endl;
cout<<t.isbalance();
}
int main(){
test();
system("pause");
return 0;
}
通过校验: