AVL平衡二叉搜索树

//简单方法实现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;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值