#include <iostream>
#include <stdlib.h>
#include <stack>
using namespace std;
template<typename Type>
struct VALNode
{
int bf;
Type data;
struct VALNode *left;
struct VALNode *right;
VALNode(Type d= Type()):bf(0),data(d),left(NULL),right(NULL){}
};
template<typename Type>
class VALTree
{
public:
VALTree():root(NULL){}
bool Insert(Type ar[],int n)
{
for(int i=0;i<n;i++)
{
Insert(root,ar[i]);
}
return true;
}
bool Insert(VALNode<Type> *&ptr,Type val)
{
VALNode<Type> *p = ptr;
VALNode<Type> *q = NULL;
VALNode<Type> *pr = NULL;
int d;
stack<VALNode<Type>* > st;
while(p!=NULL)
{
if(p->data == val)return false;
pr=p;
st.push(pr);
if(p->data>val)p=p->left;
else p=p->right;
}
p = new VALNode<Type>(val);
if(p==NULL){cout<<"no memory!!!"<<endl;exit(0);}
if(pr==NULL)
{ptr = p;return true;}
else
{
if(pr->data>val)pr->left=p;
else pr->right=p;
}
while(st.empty()!=true)
{
pr = st.top();
st.pop();
if(pr->data>p->data)
pr->bf--;
else pr->bf++;
if(pr->bf==0)break;
if(pr->bf == 1 || pr->bf == -1)
p = pr;
else
{
d = (pr->bf<0)?-1:1;//标记位判断需要旋转的形状.
if(p->bf==d)//判断是 / 或者 \ 类型。
{
if(p->bf==-1)
RotateR(pr);//右旋转.
else
RotateL(pr);
}
else//这里是 < 或者 > 类型。
{
if(d==-1)// <
{
p=p->right;//这个地方不能少,没有这句时,我开始怎么调试都不对,因为我做了LR两次翻转,所以根(翻转)节点会变.
RotateLR(pr);
}
else
RotateRL(pr);
}
}
}
if(st.empty()==true)ptr=pr;
else//链接
{
q = st.top();//ptr 还有父亲节点,这就需要将旋转的结果链接起来.
if(q->left==q)
q->left = p;
else
q->right = p;
}
return true;
}
private:
void RotateLR(VALNode<Type> *&ptr)
{
VALNode<Type> *p = ptr;
VALNode<Type> *q = p->left;
ptr = q->right;
q->right = ptr->left;
ptr->left = q;
if(ptr->bf<=0)q->bf=0;
else q->bf = -1;
p->left = ptr->right;
ptr->right = p;
if(ptr->bf==-1)p->bf=1;
else p->bf=0;
}
void RotateRL(VALNode<Type> *&ptr)
{
VALNode<Type> *p = ptr;
VALNode<Type> *q = p->right;
ptr = q->left;
q->left = ptr->right;
ptr->right = q;
if(ptr->bf>=0)q->bf=0;
else q->bf=1;
p->right = ptr->left;
ptr->left = p;
if(ptr->bf==1)q->bf=-1;
else q->bf=0;
ptr->bf=0;
}
void RotateL(VALNode<Type> *&ptr)
{
VALNode<Type> *p = ptr->right;
ptr -> right = p->left;
p->left = ptr;
p->bf = ptr->bf = 0;
}
void RotateR(VALNode<Type> *&ptr)
{
VALNode<Type> *p = ptr->left;//保存ptr的左节点p。
ptr->left = p->right;
//截肢ptr左肢,并且将p的右节点挂到ptr左肢。
p->right = ptr;
p->bf = ptr->bf = 0;
//将ptr挂载p的右肢上面,当然做到这一步还没有完成,如果ptr还有父节点呢?所以就需要我们在外面链接。
}
public:
void Remove(Type val)
{
Remove(root,val);
}
private:
bool Remove(VALNode<Type> *&ptr,Type val)
{
VALNode<Type> *pr = NULL,*p=ptr,*q,*ppr;int d,dd=0;
stack<VALNode<Type> *>st;
while(p!=NULL)
{
if(val == p->data)break;
pr=p;
st.push(pr);
if(val<p->data)p=p->left;
else p=p->right;
}
if(p==NULL)return false;
if(p->left!=NULL && p->right!=NULL)
{
pr=p;
st.push(pr);
q=p->left;
while(q->right!=NULL)
{
pr=q;
st.push(pr);
q=q->right;
}
p->data = q->data;
p=q;
}
if(p->left!=NULL)q=p->left;
else q=p->right;
if(pr==NULL)ptr=q;
else
{
if(pr->left==p)pr->left=q;
else pr->right = q;
while(!st.empty())
{
pr = st.top();
st.pop();
if(pr->right==q)pr->bf--;
else pr->bf++;
if(st.empty()==false)
{
ppr = st.top();
st.pop();
dd = (ppr->left==pr)?-1:1;
}
else dd=0;
if(pr->bf==1 || pr->bf==-1)break;
if(pr->bf!=0)
{
if(pr->bf<0){d=-1;q=pr->left;}
else{d=1;q=pr->right;}
if(q->bf==0)
{
if(d==-1)
{
RotateR(pr);pr->bf=1;pr->right->bf=-1;
}
else
{
RotateL(pr);pr->bf=-1;pr->left->bf=1;
}
break;
}
if(q->bf==d)
{
if(d==-1)RotateR(pr);
else RotateL(pr);
}
else
{
if(d==-1)RotateLR(pr);
else RotateRL(pr);
}
if(dd==-1)ppr->left=pr;
else if(dd==-1)ppr->right=pr;
}
q=pr;
}
if(st.empty()==true)ptr=pr;
}
delete p;return true;
}
public:
void show()
{
show(root);
}
void show(VALNode<Type> *t)
{
if(t==NULL)return ;
else
{
show(t->left);
cout<<t->data<< " ";
show(t->right);
}
}
private:
VALNode<Type> *root;
};
int main()
{
int a[]={4,7,5};
VALTree<int> val;
val.Insert(a,3);
val.show();
val.Remove(4);
cout<<endl;
val.show();
return 0;
}
05-13