红黑树的实现(C++)

这是做数据结构的副产品。

挺麻烦的一个东西,记录下来,以备以后只需。

红黑树的规则我不说太多,网上的资料太多。

代码之中,了无秘密:

/********************************************************************

Filename:	RBTree.h

CreatedTime:2008/06/20   10:55

Author:		fjz

Purpose:    红黑树

Version:    1.0

MODIFY:

Name:

Time:

Description:

*********************************************************************/

#pragma once

#include 

#include 

namespace DS

{

	namespace Container

	{

		/************************************

		ClassName:	RBTreeNode

		Filename:	RBTree.h

		CreatedTime:2008/06/20   11:19

		Description:红黑树节点

		************************************/

		template

		class RBTreeNode

		{

		public:

			typedef enum {RED=0,/*红色为0*/ BLACK=1/*黑色为1*/}ColorType;

			ColorType mColor;			//节点颜色

			RBTreeNode* mParent;	//父节点

			RBTreeNode* mLeft;		//左节点

			RBTreeNode* mRight;		//右节点

			ElemType mValue;			//值

			typedef RBTreeNode* LinkType;		//链接类型

			RBTreeNode()

			{

				mColor=RED;

				mLeft=NULL;

				mParent=NULL;

				mRight=NULL;

			}

			RBTreeNode(const ElemType inValue)

			{

				mValue=inValue;

				mColor=RED;

				mLeft=NULL;

				mParent=NULL;

				mRight=NULL;

			}

			RBTreeNode(const RBTreeNode& inNode)	//只复制值和颜色

			{

				mValue=inNode.mValue;

				mColor=inNode.mColor;

				mLeft=NULL;

				mParent=NULL;

				mRight=NULL;

			}

			

			

			/************************************

			CreatedTime:2008/06/20   11:24	

			MethodName: Container::RBTreeNode::GetMinNode

			Access:    	public static 

			Parameters: const RBTreeNode * inRootNode	根结点

			Returns:   	RBTreeNode*	最小的节点

			Description:得到最小的节点(最左节点)

			Remark:			

			************************************/

			static RBTreeNode* GetMinNode(const RBTreeNode* inRootNode)

			{

				if (inRootNode==NULL)

					return NULL;

				RBTreeNode* tNode=const_cast(inRootNode);

				while (tNode->mLeft!=NULL)

				{

					tNode=tNode->mLeft;

				}

				return tNode;

			}

			/************************************

			CreatedTime:2008/06/20   11:24	

			MethodName: Container::RBTreeNode::GetMaxNode

			Access:    	public static 

			Parameters: const RBTreeNode * inRootNode	根结点

			Returns:   	RBTreeNode*	最大的节点

			Description:得到最大的节点(最右节点)

			Remark:			

			************************************/

			static RBTreeNode* GetMaxNode(const RBTreeNode* inRootNode)

			{

				if (inRootNode==NULL)

					return NULL;

				RBTreeNode* tNode=const_cast(inRootNode);

				while (tNode->mRight!=NULL)

				{

					tNode=tNode->mRight;

				}

				return tNode;

			}

		};

		/************************************

		ClassName:	RBTreeIterator

		Filename:	RBTree.h

		CreatedTime:2008/06/20   13:03

		Description:红黑树迭代器

		************************************/

		template

		class RBTreeIterator

		{

		public:

			typedef ElemType ValueType;			//值类型

			typedef RefType ReferenceType;		//引用类型

			typedef PtrType PointerType;		//指针类型

			typedef RBTreeIterator Iterator;					//迭代器

			typedef RBTreeIterator ConstIterator;	//常量迭代器

			typedef	RBTreeIterator Self;							//本身

			typedef RBTreeNode* LinkType;											//链接类型

			LinkType mNode;	

		public:

			RBTreeIterator(){}

			RBTreeIterator(LinkType inNode){mNode=inNode;}

			RBTreeIterator(const RBTreeIterator& inOtherIterator){mNode=inOtherIterator.mNode;}

			void operator=(const RBTreeIterator& inOtherIterator){mNode=inOtherIterator.mNode;}

			ReferenceType operator*()const {return LinkType(mNode)->mValue;}	//取引用

			PointerType operator->()const {return &(operator*());}				//取地址

			bool operator==(const RBTreeIterator& inOtherIterator){return mNode==inOtherIterator.mNode;}

			bool operator!=(const RBTreeIterator& inOtherIterator){return mNode!=inOtherIterator.mNode;}

			Self& operator++(){Increment();return *this;}

			Self& operator++(int)

			{

				Self tInterator=*this;

				Increment();

				return tInterator;

			}

			Self& operator--(){Decrement();return *this;}

			Self operator--(int)

			{

				Self tIterator=*this;

				Decrement();

				return tIterator;

			}

			/************************************

			CreatedTime:2008/06/20   11:26	

			MethodName: Container::RBTreeIterator::Increment

			Access:    	public 

			Returns:   	void

			Description:到下一个节点

			Remark:		中序遍历的下一个节点	

			************************************/

			void Increment()

			{

				if (mNode->mRight!=NULL)		//如果有右子节点

				{

					mNode=mNode->mRight;		//先往右走

					while (mNode->mLeft!=NULL)

					{

						mNode=mNode->mLeft;		//一直向左

					}

				} 

				else							//没有右子节点

				{

					LinkType tNode=mNode->mParent;		//找出父节点

					while (mNode==tNode->mRight)			//如果本节点自己是个右节点

					{

						mNode=tNode;						//就一直向上,直到不为右节点

						tNode=tNode->mParent;

					}

					if (mNode->mRight!=tNode)			//若此时的右子节点不等于此时的父节点,此时的父节点为解

					{									//注:此状况与红黑树的有个头哑元节点有关!

						mNode=tNode;

					}

					//否则此时的mNode即可

				}

			}

			/************************************

			CreatedTime:2008/06/20   11:42	

			MethodName: Container::RBTreeIterator::Decrement

			Access:    	public 

			Returns:   	void

			Description:到上一个节点

			Remark:		中序遍历的上一个节点		

			************************************/

			void Decrement()

			{

				//注:此状况发生于mNode为Header时(mNode为End()时)

				if (mNode->mColor==RBTreeNode::RED&&mNode->mParent->mParent==mNode)	//如果是父节点,且父节点的父节点等于自己

				{

					mNode=mNode->mRight;												//右节点即为解

				} 

				else if (mNode->mLeft!=NULL)		//如果有左节点

				{

					LinkType tNode=mNode->mLeft;

					while (tNode->mRight!=NULL)			//寻找左节点的最右节点

					{

						tNode=tNode->mRight;

					}

					mNode=tNode;

				} 

				else		//非根结点,也无左节点

				{

					LinkType tNode=mNode->mParent;

					while (mNode==tNode->mLeft)			//如果本节点自己为左节点

					{

						mNode=tNode;					//一直向上,直到本节点不为左节点

						tNode=tNode->mParent;

					}

					mNode=tNode;						//此时的父节点为解

				}

			}

		};



		/************************************

		ClassName:	RBTree

		Filename:	RBTree.h

		CreatedTime:2008/06/20   15:55

		Description:红黑树

		************************************/

		template

			<

			typename Key,			//关键字类型

			typename ElemType,		//元素类型

			typename KeyOfElem,		//在元素中取得关键字的函数对象

			typename CompareType	//关键字对比函数对象

			>

		class RBTree

		{

		public:

			RBTree(void){Init();}

			~RBTree(void){Clear();delete mHeader;}

		public:

			typedef RBTreeIterator Iterator;	//迭代器类型

		protected:

			typedef Key KeyType;

			typedef RBTreeNode NodeType;				//节点类型

			typedef NodeType* LinkType;							//链接类型

			typedef typename RBTreeNode::ColorType ColorType;		//颜色类型

		protected:

			size_t mCount;		//节点数量

			LinkType mHeader;	//头哑元节点

			CompareType mCompareKey;		//比较Key的函数对象

		public:

			LinkType& GetRoot()const {return (LinkType&)mHeader->mParent;}		//得到根节点

			LinkType& GetMostLeft()const {return(LinkType&) mHeader->mLeft;}	//得到最左节点

			LinkType& GetMostRight()const {return (LinkType&)mHeader->mRight;}	//得到最右节点

		protected:

			static LinkType& GetLeft(const LinkType inNode){return inNode->mLeft;}

			static LinkType& GetRight(const LinkType inNode){return inNode->mRight;}

			static LinkType& GetParent(const LinkType inNode){return inNode->mParent;}

			static ElemType& GetValue(const LinkType inNode){return inNode->mValue;}

			static KeyType GetKey(const LinkType inNode){return KeyOfElem()(GetValue(inNode));}

			static ColorType& GetColor(const LinkType inNode){return inNode->mColor;}

			static LinkType GetMinNode(LinkType inRootNode){return RBTreeNode::GetMinNode(inRootNode);}

			static LinkType GetMaxNode(LinkType inRootNode){return RBTreeNode::GetMaxNode(inRootNode);}

		private:

			/************************************

				CreatedTime:2008/06/20   16:48	

				MethodName: DS::Container::RBTree::Init

				Access:    	private 

				Returns:   	void

				Description:初始化

				Remark:			

			************************************/

			void Init()

			{

				

				mHeader=new NodeType();

				mHeader->mColor=RBTreeNode::RED;	//头哑元的颜色为红,用于区分header和root,在iterator::operator--之中

				mHeader->mParent=NULL;					//头哑元的父节点指向红黑树的根节点,此时为NULL

				mHeader->mLeft=mHeader;					//头哑元的左节点指向红黑树的最左节点,此时为本身

				mHeader->mRight=mHeader;				//头哑元的右节点指向红黑树的最右节点,此时为本身

				mCount=0;								//节点数量为0

				//注:根节点的父节点为头哑元

			}

			

			/************************************

				CreatedTime:2008/06/20   17:08	

				MethodName: DS::Container::RBTree::InsertHelp

				Access:    	private 

				Parameters: bool inIsLeft					是否在右边插入

				Parameters: LinkType inInsertNode		插入点之父节点

				Parameters: const ElemType & inInsertValue	新值

				Returns:   	bool	是否成功

				Description:插入节点

				Remark:			

			************************************/

			bool InsertHelp(bool inIsRight,LinkType inInsertNode,const ElemType& inInsertValue);

			void RebalanceInsert(LinkType inNewNode);

			void RebalanceDelete(LinkType inNewNode);

			void RotateLeft(LinkType inNewNode);

			void RotateRight(LinkType inNewNode);

		public:

			bool Delete(LinkType inDeleteNode);

			Iterator Begin()const{return GetMostLeft();}

			Iterator End()const{return mHeader;}

			bool IsEmpty()const {return mCount==0;}

			size_t GetCout()const{return mCount;}

			bool InsertUnique(const ElemType& inValue);

			bool InsertEqual(const ElemType& inValue);

			bool Delete(const ElemType& inValue);

			Iterator Find(const KeyType& inFindKey);

			/************************************

			CreatedTime:2008/06/20   16:48	

			MethodName: DS::Container::RBTree::Clear

			Access:    	private 

			Returns:   	void

			Description:析构清除

			Remark:			

			************************************/

			void Clear()

			{

				stack st;

				LinkType p=GetRoot();

				LinkType pre=0;					//pre表示最近一次访问的结点  !!!!!!



				while(!(p==0&&st.empty()))

				{

					while(p)			//沿着左孩子方向走到最左下 。

					{

						st.push(p);

						p = p->mLeft;

					}

					p = st.top();		

					if(p->mRight==0||p->mRight==pre)	//如果p没有右孩子或者其右孩子刚刚被访问过

					{

						st.pop();

						pre=p;

						delete p;

						p=NULL;

					}

					else	p = p->mRight;

				}

				Init();

			}

			

		};

		template

		bool DS::Container::RBTree::Delete( const ElemType& inValue )

		{

			Iterator i=Find(KeyOfElem()(inValue));

			if (i==End())

			{

				return false;

			}

			return Delete(i.mNode);

		}

		template

		bool DS::Container::RBTree::Delete( LinkType inDeleteNode )

		{

			LinkType tAdjustNode,tSonNode;

			if(inDeleteNode->mLeft==NULL||inDeleteNode->mRight==NULL)

			{

				tAdjustNode=inDeleteNode;

			}

			else

			{ 

				Iterator i=Iterator(inDeleteNode);

				++i;

				tAdjustNode=i.mNode;		//后继节点

			}

			if(tAdjustNode->mLeft!=NULL)

			{

				tSonNode=tAdjustNode->mLeft;

			}

			else 

			{

				tSonNode=tAdjustNode->mRight;

			}

			if(tSonNode!=NULL)

			{

				tSonNode->mParent=tAdjustNode->mParent;

			}

			if(tAdjustNode->mParent==mHeader)	//父为头节点

			{

				GetRoot()=tSonNode;

			}

			else if(tAdjustNode==tAdjustNode->mParent->mLeft)

			{

				tAdjustNode->mParent->mLeft=tSonNode;

			}

			else

			{

				tAdjustNode->mParent->mRight=tSonNode;

			}

			if(tAdjustNode!=inDeleteNode)

			{

				inDeleteNode->mValue=tAdjustNode->mValue; 

			}

			if(tAdjustNode->mColor==RBTreeNode::BLACK)

			{

				RebalanceDelete(tSonNode);

			}

			GetMostLeft()=RBTreeNode::GetMinNode(GetRoot());

			GetMostRight()=RBTreeNode::GetMaxNode(GetRoot());

			//delete tAdjustNode;

			return true;

		}



		template

		typename DS::Container::RBTree::

			Iterator DS::Container::RBTree::Find( const KeyType& inFindKey )

		{

			LinkType tFindNode=GetRoot();

			int tCompareResult;

			while (tFindNode!=NULL)

			{

				tCompareResult=mCompareKey(inFindKey,GetKey(tFindNode));

				if (tCompareResult>0)	//大于

				{

					tFindNode=GetRight(tFindNode);

				} 

				else if(tCompareResult<0)

				{

					tFindNode=GetLeft(tFindNode);

				}

				else

				{

					return  tFindNode;

				}

			}

			return End();



		}

		template

		bool DS::Container::RBTree::InsertEqual( const ElemType& inValue )

		{

			LinkType tParentNode=mHeader;

			LinkType tInsertNode=GetRoot();

			KeyType tKey=KeyOfElem()(inValue);

			bool tCompareResult=false;		//小于等于

			while (tInsertNode!=NULL)

			{

				tParentNode=tInsertNode;

				tCompareResult=mCompareKey(tKey,GetKey(tInsertNode))>0;

				tInsertNode=tCompareResult?GetRight(tInsertNode):GetLeft(tInsertNode);

				//遇大向右,遇小等于向左

			}

			return InsertHelp(tCompareResult,tParentNode,inValue);

		}

		template

		bool DS::Container::RBTree::InsertUnique( const ElemType& inValue )

		{

			LinkType tParentNode=mHeader;

			LinkType tInsertNode=GetRoot();

			KeyType tKey=KeyOfElem()(inValue);

			bool tCompareResult=false;		//小于等于

			while (tInsertNode!=NULL)

			{

				tParentNode=tInsertNode;

				tCompareResult=mCompareKey(tKey,GetKey(tInsertNode))>0;

				tInsertNode=tCompareResult?GetRight(tInsertNode):GetLeft(tInsertNode);

				//遇大向右,遇小等于向左

			}

			if (tCompareResult==true)	//如果大于,那么必不等!

			{

				return InsertHelp(true,tParentNode,inValue);

			}

			else	//如果小于等于,那么要判断

			{

				if (mCompareKey(GetKey(tParentNode),tKey)!=0)	//不等于

				{

					return InsertHelp(false,tParentNode,inValue);

				} 

				else

				{

					return false;

				}

			}

		

		}

		template

		bool DS::Container::RBTree::InsertHelp(bool inIsRight,LinkType inInsertNode,const ElemType& inInsertValue)

		{

			LinkType inNewNode=new NodeType(inInsertValue);	//新增节点

			if (inInsertNode==mHeader)

			{

				GetRoot()=inNewNode;

				GetMostLeft()=inNewNode;

				GetMostRight()=inNewNode;

				GetParent(inNewNode)=mHeader;

			}

			else if (inIsRight==true)	//在右边插入

			{

				GetRight(inInsertNode)=inNewNode;

				if (inInsertNode==GetMostRight())

				{

					GetMostRight()=inNewNode;

				}

			} 

			else

			{

				GetLeft(inInsertNode)=inNewNode;

				if (inInsertNode==GetMostLeft())

				{

					GetMostLeft()=inNewNode;

				}

			}

			GetParent(inNewNode)=inInsertNode;

			++mCount;

			RebalanceInsert(inNewNode);

			return true;

		}

		template

		void DS::Container::RBTree::RebalanceInsert(LinkType inNewNode)

		{

			LinkType& tRootNode=GetRoot();	//根节点

			LinkType tUncleNode;			//伯父节点 

			while (inNewNode!=tRootNode&&inNewNode->mParent->mColor==RBTreeNode::RED)	//父节点为红

			{

				if (inNewNode->mParent==inNewNode->mParent->mParent->mLeft)			//父节点为祖父节点之左节点

				{

					tUncleNode=inNewNode->mParent->mParent->mRight;					//为伯父节点

					if (tUncleNode!=NULL&&tUncleNode->mColor==RBTreeNode::RED)		//伯父节点存在且为红

					{

						inNewNode->mParent->mColor=RBTreeNode::BLACK;			//父节点为黑

						tUncleNode->mColor=RBTreeNode::BLACK;					//伯父节点为黑

						inNewNode->mParent->mParent->mColor=RBTreeNode::RED;	//祖父节点为红

						inNewNode=inNewNode->mParent->mParent;						//到祖父

					} 

					else//无伯父节点或为黑

					{

						

						if(inNewNode==inNewNode->mParent->mRight)				//新节点为父节点之右节点

						{

							//此时为内侧插入,需要旋转两次

							inNewNode=inNewNode->mParent;	//到达父节点

							RotateLeft(inNewNode);			//左旋

						}

						//如果为外侧插入,则只需右旋一次

						inNewNode->mParent->mColor=RBTreeNode::BLACK;				//父节点为黑

						inNewNode->mParent->mParent->mColor=RBTreeNode::RED;		//祖父节点为红

						RotateRight(inNewNode->mParent->mParent);				//右旋

					}

				} 

				else

				{

					tUncleNode=inNewNode->mParent->mParent->mLeft;					//为伯父节点

					if (tUncleNode!=NULL&&tUncleNode->mColor==RBTreeNode::RED)		//伯父节点存在且为红

					{

						inNewNode->mParent->mColor=RBTreeNode::BLACK;			//父节点为黑

						tUncleNode->mColor=RBTreeNode::BLACK;					//伯父节点为黑

						inNewNode->mParent->mParent->mColor=RBTreeNode::RED;	//祖父节点为红

						inNewNode=inNewNode->mParent->mParent;						//到祖父

					} 

					else//无伯父节点或为黑

					{



						if(inNewNode==inNewNode->mParent->mLeft)				//新节点为父节点之左节点

						{

							//此时为内侧插入,需要旋转两次

							inNewNode=inNewNode->mParent;	//到达父节点

							RotateRight(inNewNode);			//左旋

						}

						//如果为外侧插入,则只需右旋一次

						inNewNode->mParent->mColor=RBTreeNode::BLACK;				//父节点为黑

						inNewNode->mParent->mParent->mColor=RBTreeNode::RED;		//祖父节点为红

						RotateLeft(inNewNode->mParent->mParent);				//右旋

					}

				}

			}

			tRootNode->mColor=RBTreeNode::BLACK;		//根节点永远为黑



		}

		template

		void DS::Container::RBTree::RebalanceDelete(LinkType inAdjustNode)

		{



			LinkType tRootNode=GetRoot();

			LinkType tUncleNode = NULL;



			while (inAdjustNode!=NULL&&inAdjustNode != tRootNode&&inAdjustNode->mColor == RBTreeNode::BLACK) 

			{

				if (inAdjustNode == inAdjustNode->mParent->mLeft) 

				{

					tUncleNode = inAdjustNode->mParent->mRight;

					if (tUncleNode->mColor == RBTreeNode::RED) 

					{

						tUncleNode->mColor = RBTreeNode::BLACK;

						inAdjustNode->mParent->mColor = RBTreeNode::RED;

						RotateLeft(inAdjustNode->mParent);

						tUncleNode = inAdjustNode->mParent->mRight; 

					}

					if ((tUncleNode->mLeft->mColor == RBTreeNode::BLACK) && (tUncleNode->mRight->mColor == RBTreeNode::BLACK)) 

					{

						tUncleNode->mColor = RBTreeNode::RED;

						inAdjustNode = inAdjustNode->mParent; 

					}

					else if (tUncleNode->mRight->mColor == RBTreeNode::BLACK) 

					{

						tUncleNode->mColor = RBTreeNode::RED;

						tUncleNode->mLeft->mColor = RBTreeNode::BLACK;

						RotateRight(tUncleNode);

						tUncleNode = tUncleNode->mParent;

					}

					else 

					{ 

						tUncleNode->mColor = tUncleNode->mParent->mColor;

						inAdjustNode->mParent->mColor = RBTreeNode::BLACK;

						tUncleNode->mRight->mColor = RBTreeNode::BLACK;

						RotateLeft(inAdjustNode->mParent);

						inAdjustNode = tRootNode;

					}

				}

				else

				{

					tUncleNode=inAdjustNode->mParent->mRight;          

					if(tUncleNode->mColor==RBTreeNode::RED)      

					{

						tUncleNode->mColor=RBTreeNode::BLACK;

						inAdjustNode->mParent->mColor=RBTreeNode::RED;

						RotateRight(inAdjustNode->mParent);

						tUncleNode=inAdjustNode->mParent->mLeft;                

					}

					if(tUncleNode->mLeft->mColor==RBTreeNode::BLACK&&tUncleNode->mRight->mColor==RBTreeNode::BLACK)   

					{

						tUncleNode->mColor=RBTreeNode::RED;

						inAdjustNode=inAdjustNode->mParent;                                             

					}

					else if(tUncleNode->mLeft->mColor==RBTreeNode::RED)    

					{

						tUncleNode->mRight->mColor=RBTreeNode::BLACK;

						tUncleNode->mColor=RBTreeNode::RED;

						RotateLeft(tUncleNode);

						tUncleNode=inAdjustNode->mParent->mLeft; 

					}

					tUncleNode->mColor=inAdjustNode->mParent->mColor;

					inAdjustNode->mParent->mColor=RBTreeNode::BLACK;

					tUncleNode->mLeft->mColor=RBTreeNode::BLACK;

					RotateRight(inAdjustNode->mParent);     

				}

			}

			if (inAdjustNode!=NULL)

			{

				inAdjustNode->mColor = RBTreeNode::BLACK;

			}

		}

		template

		void DS::Container::RBTree::RotateLeft(LinkType inNewNode)

		{

			LinkType tRightNode=inNewNode->mRight;		//右节点

			inNewNode->mRight=tRightNode->mLeft;

			LinkType& tRootNode=mHeader->mParent;

			if (tRightNode->mLeft!=NULL)

			{

				tRightNode->mLeft->mParent=inNewNode;

			}

			tRightNode->mParent=inNewNode->mParent;

			

			/*if (inNewNode==tRootNode)

			{

				tRootNode=tRightNode;

			} */

			if (inNewNode->mParent==mHeader)

			{

				tRootNode=tRightNode;

			}

			else if(inNewNode==inNewNode->mParent->mLeft)

			{

				inNewNode->mParent->mLeft=tRightNode;

			}

			else

			{

				inNewNode->mParent->mRight=tRightNode;

			}

			inNewNode->mRight=tRightNode->mLeft;	//此句不可忘!与<<算法导论>>的不同

			tRightNode->mLeft=inNewNode;

			inNewNode->mParent=tRightNode;

		}

		template

		void DS::Container::RBTree::RotateRight(LinkType inNewNode)

		{

			LinkType tRightNode=inNewNode->mLeft;		//左节点

			inNewNode->mRight=tRightNode->mRight;

			LinkType& tRootNode=mHeader->mParent;

			if (tRightNode->mRight!=NULL)

			{

				tRightNode->mRight->mParent=inNewNode;

			}

			tRightNode->mParent=inNewNode->mParent;

			/*if (inNewNode==tRootNode)

			{

				tRootNode=tRightNode;

			} */

			if (inNewNode->mParent==mHeader)

			{

				tRootNode=tRightNode;

			}

			else if(inNewNode==inNewNode->mParent->mRight)

			{

				inNewNode->mParent->mRight=tRightNode;

			}

			else

			{

				inNewNode->mParent->mLeft=tRightNode;

			}

			inNewNode->mLeft=tRightNode->mRight;	//此句不可忘!与<<算法导论>>的不同

			tRightNode->mRight=inNewNode;

			inNewNode->mParent=tRightNode;

		}



	}

}

你可能感兴趣的:(算法&&数据结构)