二叉搜索树有其自身的缺陷,假如往树中
插入的元素有序或者接近有序,二叉搜索树就会退化成单支树,时间复杂度会退化成
O(N)
二叉搜索树虽可以缩短查找的效率,但
如果数据有序或接近有序二叉搜索树将退化为单支树,查
找元素相当于在顺序表中搜索元素,效率低下
。因此,两位俄罗斯的数学家
G.M.Adelson-Velskii
和
E.M.Landis
在
1962
年
发明了一种解决上述问题的方法:
当向二叉搜索树中插入新结点后,如果能保证每个结点的左右
子树高度之差的绝对值不超过
1(
需要对树中的结点进行调整
)
,即可降低树的高度,从而减少平均
搜索长度。
一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:
它的左右子树都是
AVL
树
左右子树高度之差
(
简称平衡因子
)
的绝对值不超过
1(-1/0/1)
如果一棵二叉搜索树是高度平衡的,它就是
AVL
树。如果它有
n
个结点,其高度可保持在
$O(log_2 n)$
,搜索时间复杂度
O($log_2 n$)
平衡因子=右子树高度-左子树高度
#include<iostream>
#include<assert.h>
using namespace std;
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>& a)
:_kv(a)
,left(nullptr)
,right(nullptr)
,parent(nullptr)
,_bf(0)
{}
};
template<class k, class v>
struct AVLtree
{
typedef AVLtreeNode<k, v> Node;
public:
bool Insert(const pair<k, v>& a)
{
if (_root == nullptr)
{
_root = new Node(a);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (cur->_kv.first < a.first)
{
parent = cur;
cur = cur->right;
}
else if (cur->_kv.first > a.first)
{
parent = cur;
cur = cur->left;
}
else
return false;
}
cur = new Node(a);
if (parent->_kv.first > a.first)
{
parent->left = cur;
cur->parent = parent;
}
else if(parent->_kv.first < a.first)
{
parent->right = cur;
cur->parent = parent;
}
while (parent)
{
if (cur == parent->left)
{
parent->_bf--;
}
else if (cur == parent->right)
{
parent->_bf++;
}
if (parent->_bf == 0)
break;
else if (parent->_bf == 1 || parent->_bf == -1)
{
cur = parent;
parent = parent->parent;
}
else if (parent->_bf == 2 || parent->_bf == -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;
}
}
return true;
}
void RotateL(Node* parent)
{
Node* sub = parent;
Node* subp = parent->parent;
Node* subr = parent->right;
Node* t = subr->left;
if (subp == nullptr)
{
subr->parent = nullptr;
_root = subr;
}
else if (subp)
{
if (subp->right == sub)
{
subp->right = subr;
}
else if (subp->left == sub)
{
subp->left = subr;
}
subr->parent = subp;
}
if (t)
{
sub->right = t;
t->parent = sub;
}
else
{
sub->right = nullptr;
}
sub->parent = subr;
subr->left = sub;
sub->_bf = subr->_bf = 0;
/*Node* subR = parent->right;
Node* subRL = subR->left;
parent->right = subRL;
if (subRL)
subRL->parent = parent;
Node* ppNode = parent->parent;
subR->left = parent;
parent->parent = subR;
if (ppNode == nullptr)
{
_root = subR;
_root->parent = nullptr;
}
else
{
if (ppNode->left == parent)
{
ppNode->left = subR;
}
else
{
ppNode->right = subR;
}
subR->parent = ppNode;
}
parent->_bf = subR->_bf = 0;*/
}
void RotateR(Node* parent)
{
Node* subp = parent->parent;
Node* subl = parent->left;
Node* t = subl->right;
parent->left = t;
if (t)
t->parent = parent;
subl->right = parent;
parent->parent = subl;
if (subp == nullptr)
{
subl->parent = nullptr;
_root = subl;
}
else if (subp)
{
if (subp->right == parent)
{
subp->right = subl;
}
else if (subp->left == parent)
{
subp->left = subl;
}
subl->parent = subp;
}
parent->_bf= subl->_bf = 0;
//Node* subL = parent->left;
//Node* subLR = subL->right;
//parent->left = subLR;
//if (subLR)
//{
// subLR->parent = parent;
//}
//Node* ppNode = parent->parent;
//subL->right = parent;
//parent->parent = subL;
if (_root == parent)
//if (ppNode == nullptr)
//{
// _root = subL;
// _root->parent = nullptr;
//}
//else
//{
// if (ppNode->left == parent)
// {
// ppNode->left = subL;
// }
// else
// {
// ppNode->right = subL;
// }
// subL->parent = ppNode;
//}
//subL->_bf = parent->_bf = 0;
}
void RotateLR(Node* parent)
{
Node* sub = parent->left;
Node* subr = sub->right;
int bf = subr->_bf;
RotateL(parent->left);
RotateR(parent);
if (bf == -1)
{
sub->_bf = 0;
parent->_bf = 1;
subr->_bf = 0;
}
else if (bf == 1)
{
parent->_bf = 0;
sub->_bf = -1;
subr->_bf = 0;
}
else if (bf == 0)
{
parent->_bf = 0;
sub->_bf = 0;
subr->_bf = 0;
}
else
{
assert(false);
}
}
void RotateRL(Node* parent)
{
Node* sub = parent->right;
Node* subl = sub->left;
int bf = subl->_bf;
RotateR(parent->right);
RotateL(parent);
if (bf == -1)
{
sub->_bf = 1;
parent->_bf = 0;
subl->_bf = 0;
}
else if (bf == 1)
{
parent->_bf = -1;
sub->_bf = 0;
subl->_bf = 0;
}
else if (bf == 0)
{
parent->_bf = 0;
sub->_bf = 0;
subl->_bf = 0;
}
else
{
assert(false);
}
}
void Inorder()
{
_Inorder(_root);
}
void _Inorder(Node* root)
{
if (root == nullptr)
return;
_Inorder(root->left);
cout << root->_kv.first << ":" << root->_kv.second << endl;
_Inorder(root->right);
}
int Height(Node* node)
{
if (node == nullptr)
return 0;
return max(Height(node->left), Height(node->right)) + 1;
}
bool isblance()
{
return _isblance(_root);
}
bool _isblance(Node* node)
{
if (node == nullptr)
return true;
int highr = Height(node->right);
int highl = Height(node->left);
if (highr - highl != node->_bf)
{
cout <<node->_kv.first<< "平衡因子出错" << endl;
return false;
}
return abs(highr - highl) < 2 && _isblance(node->right) && _isblance(node->left);
}
private:
Node* _root = nullptr;
};
void testtree()
{
//int a[5] = { 4,2,6,1,3 };
srand(time(0));
AVLtree<int, int> t;
for (int i=0;i<1000;i++)
{
int k = rand();
t.Insert(make_pair(k,k));
}
t.Inorder();
cout << t.isblance() << endl;
}