您的位置:首页 > 其它

avl树

2011-11-08 00:27 316 查看
#include<time.h>

#include<iostream>

#include<stack>

using namespace std;

template<class E>

struct AVLNode

{

int bf;   //ÆœºâÒò×Ó balance factor

AVLNode *leftchild;  //leftchild

AVLNode *rightchild; //rightchild

E data;

AVLNode(E el){ data=el;bf=0;leftchild=NULL;rightchild=NULL;};

};

template<class E>

class AVLTree

{

public:

AVLTree():root(NULL){};          //construtor

bool Insert(E el);              //insert new node

bool Remove(E el);              //remove the node

void output(ostream &out);       //output the AVLTree by inorder

private:

AVLNode<E> *root;                //root of avl Tree

void RotateL(AVLNode<E> *&ptr);  //rotation left

void RotateR(AVLNode<E> *&ptr);  //rotation right

void RotateLR(AVLNode<E> *&ptr); //rotation left right

void RotateRL(AVLNode<E> *&ptr); //rotation right left

void Traverse(AVLNode<E> *ptr,ostream &out); //traverse the tree inorder

};

//remove a node

//@param

//el  the key of the node to be removed

//if the node is removed successfully ,return true,else return false

template<class E>

bool AVLTree<E>::Remove(E el)

{

AVLNode<E> *pr=NULL,*p=root,*q,*ppr;

int d,dd=0;

stack<AVLNode<E> *>st;

while(p!=NULL)        //Ñ°ÕÒÉŸ³ýλÖÃ

{

if(el==p->data)break;  //ÕÒµœµÈÓÚkµÄœáµã Í£Ö¹ËÑË÷

pr=p;

st.push(pr);     //ÓÃÕ»ŒÇÒä²éÕÒ·Ÿ¶

if(el<p->data)p=p->leftchild;

else p=p->rightchild;

}

if(p==NULL) return false;     //ÎŽÕÒµœ±»ÉŸœáµã£¬ÉŸ³ýʧ°Ü

if(p->leftchild!=NULL&&p->rightchild!=NULL)  //±»ÉŸœáµãÓÐÁœžö×ÓÅ®

{

pr=p;

st.push(pr);

q=p->leftchild;                    //ÔÚp×ö×ÖÊýÕÒpµÄÖ±œÓÇ°Çý

while(q->rightchild!=NULL)

{

pr=q;

st.push(pr);

q=q->rightchild;

}

p->data=q->data;

p=q;

}

if(p->leftchild!=NULL)q=p->leftchild;

else q=p->rightchild;

if(pr==NULL)root=q;

else

{

if(pr->leftchild==p)pr->leftchild=q;

else pr->rightchild=q;

while(st.empty()==false)   //ÖØÐÂÆœºâ»¯

{

pr=st.top();

st.pop();

if(pr->rightchild==q)pr->bf--;

else pr->bf++;

if(st.empty()==false)

{

ppr=st.top();

dd=(ppr->leftchild==pr)?-1:1;

}

else dd=0;            //Õ»¿Õ Ðýתºó²»ÓÃÓëÉϲãÁŽœÓ

if(pr->bf==1||pr->bf==-1)break;

if(pr->bf!=0)           //|bf|=2

{

if(pr->bf<0)

{

d=-1;

q=pr->leftchild;

}

else

{

d=1;

q=pr->rightchild;

}

if(q->bf==0)

{

if(d==-1)

{

RotateR(pr);

pr->bf=1;

pr->leftchild->bf=-1;

}

else

{

RotateL(pr);

pr->bf=-1;

pr->rightchild->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->leftchild=pr;

else if(dd==1)ppr->rightchild=pr;

}

q=pr;

}

if(st.empty()==true)root=pr;

}

delete p;

return true;

}

//output the AVLTree inorder

//@param

//out  the ostream

template<class E>

void AVLTree<E>::output(ostream &out)

{

out<<"Inorder traversal of AVL Tree.\n";

Traverse(root,out);

out<<endl;

}

//Traverse the AVLTree inorder

//@param

//ptr the root of tree

//out the ostream

template<class E>

void AVLTree<E>::Traverse(AVLNode<E> *ptr,ostream &out)

{

if(ptr==NULL)return;

Traverse(ptr->leftchild,out);

out<<ptr->data<<"  ";

Traverse(ptr->rightchild,out);

}

//insert new node into the AVLTree

//@param el new element to insert

//if insert successfully ,return true,else return false

template<class E>

bool AVLTree<E>::Insert(E el)

{

AVLNode<E> *pr=NULL,*p=root,*q;

stack<AVLNode<E> *> st;

while(p!=NULL)

{                 //Ñ°ÕÒ²åÈëλÖÃ

if(el==p->data) return false;  //ÕÒµœµÈÓÚelµÄœáµã£¬²»²åÈë

pr=p;

st.push(pr);

if(el<p->data)p=p->leftchild;

else  p=p->rightchild;

}

p=new AVLNode<E>(el);              //ŽŽœšÒ»žöÐÂœáµã£¬data=el,bf=0;

if(p==NULL)

{

cerr<<"ŽæŽ¢¿ÕŒä²»×ã!"<<endl;

exit(1);

}

if(pr==NULL)

{

root=p;     //¿ÕÊ÷£¬ÐÂœáµã³ÉΪžùœáµã

return true;

}

if(el<pr->data) pr->leftchild=p; //²åÈëÐÂœáµã

else pr->rightchild=p;

while(st.empty()==false)

{ //ÖØÐÂÆœºâ»¯

pr=st.top();

st.pop();

if(p==pr->leftchild) pr->bf--;

else pr->bf++;

if(pr->bf==0)break;  //²åÈëÖ®ºóÆœºâ  Í˳ö

if(pr->bf==1||pr->bf==-1)  //|bf|=1  ÔòŒÌÐøÏòÉÏÕÒ²»ÆœºâµÄœáµã

p=pr;

else                       //|bf|=2,Ôòµ÷Õû

{

int d=(pr->bf<0)?-1:1; //ÉÏÃæœáµãµÄ·ûºÅ

if(p->bf==d)           //ÁœžöœáµãÆœºâÒò×ÓͬºÅ£¬µ¥Ðý

{

if(d==-1) RotateR(pr);

else RotateL(pr);

}

else

{

if(d==-1) RotateLR(pr);

else RotateRL(pr);

}

break;  //²»ÔÙÏòÉϵ÷Õû

}

}

if(st.empty()) root=pr;  //µ÷ÕûµœÊ÷µÄžùœÚµã

else

{

q=st.top();

if(q->data>pr->data)q->leftchild=pr;

else q->rightchild=pr;

}

return true;

}

//rotation left right

//@param

//ptr the root of the tree to be rotated

template<class E>

void AVLTree<E>::RotateLR(AVLNode<E> *&ptr)

{

AVLNode<E> *subR=ptr,*subL=subR->leftchild;

ptr=subL->rightchild;

subL->rightchild=ptr->leftchild;

subR->leftchild=ptr->rightchild;

ptr->leftchild=subL;

ptr->rightchild=subR;

if(ptr->bf<=0)subL->bf=0;

else subL->bf=-1;

if(ptr->bf==-1)subR->bf=1;

else subR->bf=0;

ptr->bf=0;

}

//rotation right left

//@param

//ptr the root of the tree to be rotated

template <class E>

void AVLTree<E>::RotateRL(AVLNode<E> *&ptr)

{

AVLNode<E> *subL=ptr,*subR=subL->rightchild;

ptr=subR->leftchild;

subL->rightchild=ptr->leftchild;

subR->leftchild=ptr->rightchild;

ptr->leftchild=subL;

ptr->rightchild=subR;

if(ptr->bf>=0)subR->bf=0;

else subR->bf=1;

if(ptr->bf==1)subL->bf=-1;

else subL->bf=0;

ptr->bf=0;

}

//rotation left

//@param

//ptr the root of the tree to be rotated

template<class E>

void AVLTree<E>::RotateL(AVLNode<E> *&ptr)

{

AVLNode<E> *subL=ptr;

ptr=subL->rightchild;

subL->rightchild=ptr->leftchild;

ptr->leftchild=subL;

ptr->bf=subL->bf=0;

}

//rotation right

//@param

//ptr  the root of the tree to be rotated

template<class E>

void AVLTree<E>::RotateR(AVLNode<E> *&ptr)

{

AVLNode<E> *subR=ptr;

ptr=subR->leftchild;

subR->leftchild=ptr->rightchild;

ptr->rightchild=subR;

subR->bf=0;

ptr->bf=0;

}

int _tmain(int argc, _TCHAR* argv[])

{

int n;

srand(unsigned int(time(0)));

n=rand()%5+5;

int *arr=new int
;

for(int i=0;i<n;i++)

{

arr[i]=rand()%100;

cout<<arr[i]<<"  ";

}

cout<<endl;

AVLTree<int> myAVLTree;

for(int i=0;i<n;i++)

{

myAVLTree.Insert(arr[i]);

}

myAVLTree.output(cout);

myAVLTree.Remove(arr[0]);

myAVLTree.output(cout);

myAVLTree.Remove(arr[n-1]);

myAVLTree.output(cout);

myAVLTree.Remove(arr[n/2]);

myAVLTree.output(cout);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: