AVL树:保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度。
AVL树的性质:(1)左子树和右子树的高度之差的绝对值不超过1
(2)树中的每个左子树和右子树都是AVL树。
结点的平衡因子 = 右边高度 — 左边高度
以下为需要进行结点调平的四种情况:
(1)当当前结点的平衡因子为 -1,其父结点 时的平衡因子为 -2,右单旋调整
(2)当当前结点的平衡因子为 1,其父结点 时的平衡因子为 2,左单旋调整
(3)当当前结点的平衡因子为 -1,其父结点 时的平衡因子为 2,右左双旋调整
(4)当当前结点的平衡因子为 1,其父结点 时的平衡因子为 -2,左右双旋调整
平衡因子的调整方式:从当前不平衡结点开始,依次向上调整,根据孩子结点的左右情况,对平衡因子 +1/-1操作,当调整到有结点的平衡因子为0时,即调整结束。
部分相关操作如下:
#pragma once
template<class K,class V>
struct AVLTreeNode
{
AVLTreeNode<K, V>* _parent;
AVLTreeNode<K, V>* _left;
AVLTreeNode<K, V>* _right;
K _key;
V _value;
int _bf;
AVLTreeNode<K,V>(const K& key, const V& value)
:_parent(NULL)
, _left(NULL)
, _right(NULL)
, _key(key)
, _value(value)
, _bf(0)
{}
};
template<class K,class V>
class AVLTree
{
typedef AVLTreeNode<K, V> Node;
public:
AVLTree()
:_root(NULL)
{}
bool Insert(const K&key, const V&value)
{
if (_root == NULL)
{
_root = new Node(key, value);
return true;
}
Node*parent = NULL;
Node*cur = _root;
//1、找到插入的位置
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key>key)
{
parent = cur;
cur = cur->_left;
}
else
return false;
}
cur = new Node(key, value);
cur->_parent = parent;
if (key < parent->_key)
parent->_left = cur;
else
parent->_right = cur;
//2.调整平衡因子
while (parent)
{
if (parent->_left == cur)
parent->_bf--;
else
parent->_bf++;
if (parent->_bf == 0)
break;
else if (parent->_bf == -1 || parent->_bf == 1)
{
cur = parent;
parent = parent->_parent;
}
else//开始旋转 -2/2
{
if (parent->_bf == -2)
{
if (cur->_bf == -1)
RorateR(parent);
else
{
RorateLR(parent);
}
}
else
{
if (cur->_bf == 1)
RorateL(parent);
else
{
RorateRL(parent);
}
}
break;
}
}
return true;
}
bool IsBlance()
{
return _IsBlance(_root);
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
protected:
int Height(Node*root)
{
if (root == NULL)
return 0;
else if (root->_left == NULL&&root->_right == NULL)
return 1;
else
{
int left = Height(root->_left);
int right = Height(root->_right);
return 1 + (left > right ? left : right);
}
}
bool _IsBlance(Node*root)
{
if (root == NULL)
return true;
int left = Height(root->_left);
int right = Height(root->_right);
if (abs(right - left) <= 1)
return _IsBlance(root->_left) && _IsBlance(root->_right);
else
return false;
}
void RorateR(Node*parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
Node*ppNode = parent->_parent;
parent->_left = subLR;
if (subLR)
subLR->_parent = parent;
subL->_right = parent;
parent->_parent = subL;
if (ppNode == NULL)
{
_root = subL;
subL->_parent = NULL;
}
else
{
if (ppNode->_left == parent)
ppNode->_left = subL;
else
ppNode->_right = subL;
subL->_parent = ppNode;
}
parent->_bf = subL->_bf = 0;
}
void RorateL(Node*parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
Node* ppNode = parent->_parent;
parent->_right = subRL;
if (subRL)
subRL->_parent = parent;
subR->_left = parent;
parent->_parent = subR;
if (ppNode == NULL)
{
_root = subR;
subR->_parent = NULL;
}
else
{
if (ppNode->_left == parent)
ppNode->_left = subR;
else
ppNode->_right = subR;
subR->_parent = ppNode;
}
parent->_bf = subR->_bf= 0;
}
void RorateLR(Node*parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
int bf = subLR->_bf;
RorateL(parent->_left);
RorateR(parent);
if (bf == 1)
{
subL->_bf = -1;
parent->_bf = 0;
}
else if (bf == -1)
{
subL->_bf = 0;
parent->_bf = 1;
}
}
void RorateRL(Node*parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
int bf = subRL->_bf;
RorateR(parent->_right);
RorateL(parent);
if (bf == 1)
{
subR->_bf = 0;
parent->_bf = -1;
}
else if (bf == -1)
{
subR->_bf = 1;
parent->_bf = 0;
}
}
void _InOrder(Node*root)
{
if (root == NULL)
return;
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
public:
Node* _root;
};