avl树

#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 [n];

	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;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值