AVL平衡树
// AVLTree #include<iostream> #include<string.h> #include<stdio.h> #include<string> #include<stddef.h> #include<queue> #include<fstream> using namespace std; int cnt=0; #define abs(x) (((x)<0)?(-x):(x)) typedef string Int; struct AVLNode{ AVLNode *chi[2],*pa; Int val; int bf,cnt; int blank,len,hei; }*nil=new AVLNode(),*root=nil; void Doit(){}; inline void Nil(){ nil->chi[0]=nil->chi[1]=nil->pa=nil; nil->bf=nil->cnt=0; nil->blank=nil->len=nil->hei=0; } inline AVLNode * CreatNode(AVLNode * &node,Int val,int cnt=1){ if(node!=NULL && node!=nil){ AVLNode *p=node; delete p; } node=new AVLNode(); node->val=val; node->cnt=cnt; node->pa=node->chi[0]=node->chi[1]=nil; node->bf=0; return node; } inline void Connect(AVLNode *pa,AVLNode *node,int dir) { pa->chi[dir]=node; node->pa=pa; } AVLNode * Bound(AVLNode * node,Int val){ if(node==nil) return nil; for(int dir;val!=node->val;node=node->chi[dir]){ dir=(val<node->val)?0:1; if(node->chi[dir]==nil) return node; } return node; } AVLNode * Extrema(AVLNode * node,int dir){ while(node->chi[dir]!=nil) node=node->chi[dir]; return node; } AVLNode * Cessor(AVLNode * node,int dir){ if(node->chi[dir]!=nil) return Extrema(node->chi[dir],1-dir); for(AVLNode * p=node->pa;p!=nil && p->chi[dir]==node;node=p,p=p->pa); return node->pa; } void Rotate(AVLNode *node,int rodir){ Nil(); AVLNode *pivot=node->chi[1-rodir]; Connect(node,node->chi[1-rodir]->chi[rodir],1-rodir); Connect(node->pa,pivot,(node->pa->chi[0]==node)?0:1); Connect(pivot,node,rodir); Nil(); if(root==node) root=pivot; // !!!!!! if(rodir){ node->bf+=(pivot->bf<0)?(1-pivot->bf):1; pivot->bf+=(node->bf<0)?1:(1+node->bf); } else{ node->bf+=(pivot->bf>=0)?(-pivot->bf-1):-1; pivot->bf+=(node->bf>=0)?-1:(node->bf-1); } Doit(); } AVLNode * Search(AVLNode *root,Int val){ AVLNode *p=Bound(root,val); if(p->val==val) return p; return nil; } void Balance(AVLNode * node,int dbf,int aimbf){ for((node->bf)+=dbf;aimbf!=abs(node->bf);(node->bf)+=(aimbf)?-dbf:dbf){ dbf=(node->pa->chi[0]==node)?-1:1; Doit(); if(abs(node->bf)==2){ int dir=(node->bf<0)?0:1; if((node->bf)*(node->chi[dir]->bf)<0) Rotate(node->chi[dir],dir); Rotate(node,1-dir); node->pa->bf-=dbf; } if((node=node->pa)==nil) { Nil(); return;} } Nil(); cout<<endl<<"Balenced!"<<endl; } void Insert(AVLNode * &root,Int val){ if(root==nil){ root=CreatNode(root,val); Doit(); return; } Nil(); AVLNode *p=Bound(root,val); if(p->val==val){ p->cnt++; return; } int dir=(val<p->val)?0:1; AVLNode *node=nil; CreatNode(node,val); Connect(p,node,dir); Doit(); Balance(p,(!dir)?-1:1,0); Nil(); Doit(); } bool Delete(AVLNode *&root,Int val){ if(root==nil) return false; Nil(); AVLNode *p=Search(root,val); if(p==nil) return false; if(p->cnt>1){ (p->cnt)--; return true; } if(p->chi[0]!=nil || p->chi[1]!=nil){ AVLNode *suc=Cessor(p,1); if(suc==nil) suc=Cessor(p,0); p->val=suc->val; p->cnt=suc->cnt; p=suc; } int dir=p->pa->chi[0]==p?0:1; p->pa->chi[dir]=nil; Balance(p->pa,(!dir)?1:-1,1); if(p!=root) delete p; else {AVLNode * t=p; root=nil; delete t;} Doit(); Nil(); return true; } void Traversal(AVLNode * root){ if(root->chi[0]!=nil) Traversal(root->chi[0]); cout<<root->val; printf(" %.4lf\n",(double)root->cnt/(double)cnt*100.0); // double if(root->chi[1]!=nil) Traversal(root->chi[1]); } int main(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); string s; while (getline(cin,s)) if(s!="" && ++cnt){ Insert(root,s); if(root!=nil){ Delete(root,s); Insert(root,s);} } Traversal(root); return 0; }