//简单方法实现AVL的插入
#pragma once
#include<stack>
template<class Type>
class AVLTree;
template<class Type>
class AVLNode
{
friend class AVLTree<Type>;
public:
AVLNode():data(Type()),df(0),leftChild(NULL),rightChild(NULL)
{}
AVLNode(Type t,AVLNode<Type>* left = NULL,AVLNode<Type>* right = NULL):data(t),bf(0),leftChild(left),rightChild(right)
{}
~AVLNode()
{}
private:
Type data;
int bf;
AVLNode<Type>* leftChild;
AVLNode<Type>* rightChild;
};
template<class Type>
class AVLTree
{
public:
AVLTree():root(NULL)
{}
public:
bool insert(Type &x)
{return insert(root,x);}
bool remove(const Type &x)
{
return remove(root,x);
}
protected:
bool remove(AVLNode<Type> *&t,const &x)
{
AVLNode<Type> * p = t;
AVLNode<Type> *pr = NULL;
stack<AVLNode<Type>*> st;
while(p != NULL)
{
if(x == p->data)
break;
pr = p;
st.push(pr);
if(x > p->data)
p = p->rightChild;
else
p = p->leftChild;
}
if(p == NULL)//查找失败
return false;
AVLNode<Type> *q = NULL;
if(p->leftChild!=NULL && p->rightChild!=NULL)
{
pr = p;
st.push(pr);
q = p->leftChild;
while(q->rightChild!=NULL)
{
pr = q;
st.push(pr);
q = q->rightChild;
}
p->data = q->data;
p = q;//p为要删除的结点
}
if(p->leftChild!=NULL)
q = p->leftChild;
else
q = p->rightChild;
if(pr == NULL)
t = p;
else
{
if(pr->leftChild == p)
pr->leftChild = q;
else
pr->rightChild = q;
///////调整平衡因子??????????????????????????
while(!st.empty())
{
pr = st.top();
st.pop();
if(pr->leftChild == q)
pr->bf++;//?????????
else
pr->bf--;
if(pr->bf == 1 || pr->bf == -1)
break;
else if(pr->bf == 0)
q = pr;
else
{
if(pr->bf >0)
q = pr->rightChild;
else
q = pr->leftChild;
if(q->bf == 0)
{
if(pr->bf > 0)
{
RotateL(pr);
pr->bf = -1;
pr->leftChild->bf = 1;
}
else
{
RotateR(pr);
pr->bf = 1;
pr->rightChild->bf = -1;
}
}
else
{
if(q->bf<0 && pr->bf<0)
{
RotateR(pr);
}
else if(q->bf>0 && pr->bf>0)
{
RotateL(pr);
}
else if(q->bf<0 && pr->bf>0)
{
RotateRL(pr);
}
else if(q->bf>0 && pr->bf<0)
{
RotateLR(pr);
}
}
break;
}
}
//调整后重新连接
if(st.empty())
t = pr;
else
{
AVLNode<Type> * tmp = st.top();
if(tmp->data>pr->data)
tmp->leftChild = pr;
else
tmp->rightChild = pr;
}
}
delete p;
return true;
}
bool insert(AVLNode<Type> *&t,Type &x)
{
AVLNode<Type> *p=t;
AVLNode<Type> *pr=NULL;
stack<AVLNode<Type>* >st;//用栈来跟踪结点,保留pr轨迹
while(p!=NULL)
{
pr = p;
st.push(pr);
if(x > p->data)
p = p->rightChild;
else if(x < p->data)
p = p->leftChild;
else
return false;
}
p = new AVLNode<Type>(x);
if(pr == NULL)//当只有一个节点的情况
{
t = p;
return true;
}
if(pr->data > x)
pr->leftChild = p;
else
pr->rightChild = p;
while(!st.empty())
{
pr = st.top();
st.pop();//取出栈顶元素,出栈
if(pr->leftChild == p)//算出平衡因子
pr->bf--;
else
pr->bf++;
//判断该二叉树是否平衡,并使之平衡
if(pr->bf == 0)
break;//平衡因子为0,则平衡
else if(pr->bf == 1 || pr->bf == -1)
p = pr;
else
{
if(pr->bf > 0)
{
if(p->bf > 0)
{
RotateL(pr);
//cout<<"LEFT."<<endl;//
}
else
{
RotateRL(pr);
//cout<<"RIGHT--LEFT."<<endl;// >
}
}
else
{
if(p->bf < 0)
{
RotateR(pr);
// cout<<"RIGHT."<<endl;// /
}
else
{
RotateLR(pr);
cout<<"LEFT--RIGHT."<<endl;// <
}
}
break;
}
}
//调整后,将改变的pr重新连接
if(st.empty())
t = pr;
else
{
AVLNode<Type> *q = st.top();
if(pr->data < q->data)
q->leftChild = pr;
else
q->rightChild = pr;
}
return true;
}
protected:
void RotateL(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subL = ptr;
ptr = subL->rightChild;
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
ptr->bf = subL->bf = 0;
}
void RotateR(AVLNode<Type> *&ptr)
{
AVLNode<Type> * subR = ptr;
ptr = subR->leftChild;
subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
ptr->bf = subR->bf = 0;
}
void RotateLR(AVLNode<Type> *&ptr)
{
AVLNode<Type>* subR = ptr;
AVLNode<Type>* subL = subR->leftChild;
ptr = subL->rightChild;
//turn left
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
//调整平衡因子
if(ptr->bf >0 )
subL->bf = -1;
else
subL->bf = 0;
//turn right
subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
//调整平衡因子
if(ptr->bf < 0)
subR->bf = 1;
else
subR->bf = 0;
ptr->bf = 0;
}
void RotateRL(AVLNode<Type> *&ptr)
{
AVLNode<Type>* subL = ptr;
AVLNode<Type>* subR = subL->rightChild;
ptr = subR->leftChild;
//turn right
subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
if(ptr->bf < 0)
subR->bf = 1;
else
subR->bf = 0;
//turn left
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
if(ptr->bf >0 )
subL->bf = -1;
else
subL->bf = 0;
ptr->bf = 0;
}
private:
AVLNode<Type>* root;
};