实现红黑树中

 

2013-3-19 23:02 完成红黑树的插入操作,红黑树的搜索与搜索二叉树的搜索函数是相同的。每天抽点时间看书。

 

//BLTreePractise.cpp

#include "BlackRedTree.h"

void main()
{
 BlackRedTree<int> Bl;
 int a[] = {1,2,3,9,5,4,10,6,8,7};
 for(int i= 0;i<sizeof(a)/sizeof(int);i++)
 {
  //cout<<"a[i]:"<<a[i]<<endl;
  cout<<"===================="<<endl;
  Bl.Insert(a[i]);
  
  Bl.PrintTree();
 }
 
 return;
}


 

 

//BlackRedTree.h

#ifndef __BLACK_RED_TREE
#define __BLACK_RED_TREE

#include <iostream>

using namespace std;

#define RED 1
#define BLACK 0

#define OutMsg(FunName) (cout<<FunName<<endl)

template<class T> class BlackTree;

template<class T> class BlackRedNode
{
public:
	template<class T> friend class BlackRedTree;
	BlackRedNode():Color(BLACK),Left(NULL),Right(NULL),Parent(NULL){;}
	BlackRedNode(const T& e,int NodeColor=BLACK,BlackRedNode<T>* LeftNode=NULL,BlackRedNode<T>* RightNode=NULL,BlackRedNode<T>* ParentNode=NULL):Data(e),Color(NodeColor),Left(LeftNode),Right(RightNode),Parent(ParentNode){;}
	

private:
	T Data;
	int Color;//0:black,1:red
	BlackRedNode<T>* Left,*Right;
	BlackRedNode<T>* Parent;

	
};

template<class T> class BlackRedTree
{
public:
	BlackRedTree():Root(NULL){;}
	BlackRedTree(const T& x);
	BlackRedTree<T>& Insert(const T& e);

	bool AdjustColorAfterInsert(BlackRedNode<T>* Node); //Node为新插入节点的指针。插入节点之后,判断是否违反RB2,如果违反则进行调整
	//XYr类型,调整之后,可能还需要继续调整
	bool LXr_AfterInsert(BlackRedNode<T>* Node);//插入之后,如果为LXr形式,则进行相应调整,其他与此类似,Node为插入的元素指针。X为L或者R
	bool RXr_AfterInsert(BlackRedNode<T>* Node);//插入之后为RXr类型:X为R或者L;
	//XYb类型,调整之后不再需要继续调整
	bool LLb_AfterInsert(BlackRedNode<T>* Node);
	bool LRb_AfterInsert(BlackRedNode<T>* Node);
	bool RRb_AfterInsert(BlackRedNode<T>* Node);
	bool RLb_AfterInsert(BlackRedNode<T>* Node);

	void PrintTree() const{PrintTree(Root,0);}//打印红黑树
	

private:

	void PrintTree(BlackRedNode<T>* Node,int Layer)const;

	BlackRedNode<T>* Root;

	

};

template<class T> BlackRedTree<T>::BlackRedTree(const T& x)
{
	Root = new BlackRedNode<T>(x);
}

template<class T> BlackRedTree<T>& BlackRedTree<T>::Insert(const T& e)
{
	if(!Root)
	{
		Root = new BlackRedNode<T>(e);
		return *this;
	}
	BlackRedNode<T>* Temp,*pTemp;
	int InsertDirection = 0;//0:左,1:右

	Temp = Root;
	while(Temp)
	{
		pTemp = Temp;
		if(e > Temp->Data)
		{
			Temp = Temp->Right;
			InsertDirection = 1;
		}
		else
		{
			Temp = Temp->Left;
			InsertDirection = 0;
		}
		if(Temp)
		{
			Temp->Parent = pTemp;
		}
	}
	//这里的temp即为要插入的位置
	Temp = new BlackRedNode<T>(e,RED);
	Temp->Parent = pTemp;
	if(InsertDirection)
	{
		pTemp->Right = Temp;
	}
	else
	{
		pTemp->Left = Temp;
	}
	//接下来调整颜色
	AdjustColorAfterInsert(Temp);
	return *this;

}

template<class T> bool BlackRedTree<T>::AdjustColorAfterInsert(BlackRedNode<T>* Node)
{

	BlackRedNode<T>* PNode,*GNode;
	if(Node == Root)
	{
		Root->Color = BLACK;
		return true;
	}
	PNode = Node->Parent;
	if(PNode->Color == BLACK)
	{
		cout<<"PNode->Color == BLACK,这时候不需要调整颜色"<<endl;
		return true;
	}
	//既然PNode是红色的,那么一定有GNode存在,而且GNode一定是黑色的
	GNode = PNode->Parent;
	
	//一共有8种情况:LLr,LRr,RRr,RLr,LLb,LRb,RRb,RLb.(这种情况包括gu的另一个孩子是外部节点的情况)
	if(PNode == GNode->Left && (GNode->Right!=NULL && GNode->Right->Color == RED))//LXr
	{
		LXr_AfterInsert(Node);
		return AdjustColorAfterInsert(GNode);
	}

	if(PNode == GNode->Right && (GNode->Left!=NULL && GNode->Left->Color == RED))//RXr
	{
		RXr_AfterInsert(Node);
		return AdjustColorAfterInsert(GNode);
	}

	if(PNode == GNode->Left && Node == PNode->Left && (GNode->Right ==NULL || (GNode->Right!=NULL && GNode->Right->Color == BLACK) ))//LLb
	{
		return LLb_AfterInsert(Node);
	}
	
	if(PNode == GNode->Left && Node == PNode->Right && (GNode->Right ==NULL || (GNode->Right!=NULL && GNode->Right->Color == BLACK) ))//LRb
	{
		return LRb_AfterInsert(Node);
	}
	if(PNode == GNode->Right && Node == PNode->Right && (GNode->Left == NULL || (GNode->Left!=NULL && GNode->Left->Color == BLACK)))//RRb
	{
		return RRb_AfterInsert(Node);
	}
	if(PNode == GNode->Right && Node == PNode->Left && (GNode->Left == NULL || (GNode->Left!=NULL && GNode->Left->Color == BLACK)))//RLb
	{
		return RLb_AfterInsert(Node);
	}

}

template<class T> bool BlackRedTree<T>::LXr_AfterInsert(BlackRedNode<T>* Node)
{
	OutMsg("LXr_AfterInsert");
	BlackRedNode<T>* PNode,*GNode;
	PNode = Node->Parent;
	GNode = PNode->Parent;
	if( PNode!= GNode->Left || GNode->Right == NULL || (GNode->Right!=NULL && GNode->Right->Color!=RED) )
	{
		cout<<"插入节点之后,不是LXr类型"<<endl;
		return true;
	}
	//根据数据结构上给出的算法进行颜色调整
	GNode->Color = RED;
	PNode->Color = BLACK;
	GNode->Right->Color = BLACK;
	//这样调整完之后,可能还存在违反RB2,这个交给AdjustColorAfterInsert函数来处理
	return true;
}

template<class T> bool BlackRedTree<T>::RXr_AfterInsert(BlackRedNode<T>* Node)
{
	OutMsg("RXr_AfterInsert");
	BlackRedNode<T>* PNode,*GNode;
	PNode = Node->Parent;
	GNode = PNode->Parent;
	if(PNode!= GNode->Right || (GNode->Left!=NULL && GNode->Left->Color!=RED))
	{
		cout<<"插入节点之后,不是RXr类型"<<endl;
		return true;
	}
	//根据数据结构上给出的算法进行颜色调整
	GNode->Color = RED;
	PNode->Color = BLACK;
	GNode->Left->Color = BLACK;
	//这样调整完之后,可能还存在违反RB2,这个交给AdjustColorAfterInsert函数来处理
	return true;
}


template<class T>  bool BlackRedTree<T>::LLb_AfterInsert(BlackRedNode<T>* Node)
{
	OutMsg("LLb_AfterInsert");
	BlackRedNode<T>* PNode,*GNode;
	PNode = Node->Parent;
	GNode = PNode->Parent;
	if(PNode!= GNode->Left || Node!= PNode->Left || (GNode->Right!=NULL && GNode->Right->Color!=BLACK))
	{
		cout<<"插入节点之后,不是LLb类型"<<endl;
		return true;
	}
	//根据数据结构上给出的算法进行旋转
	BlackRedNode<T>* NewNode,*NodeToDelete; 
	NewNode = new BlackRedNode<T>(GNode->Data,RED);
	NodeToDelete = GNode->Left;

	NewNode->Left = NodeToDelete->Right;
	NewNode->Right = GNode->Right;
	
	GNode->Left = NodeToDelete->Left;
	GNode->Right = NewNode;
	GNode->Data = NodeToDelete->Data;
	//调整父节点
	if(NewNode)
	{
		NewNode->Parent = GNode;
		if(NewNode->Left)
		{
			NewNode->Left->Parent = NewNode;
		}
		if(NewNode->Right)
		{
			NewNode->Right->Parent = NewNode;
		}
	}
	if(GNode->Left)
	{
		GNode->Left->Parent = GNode;
	}
	if(GNode->Right)
	{
		GNode->Right->Parent = GNode;
	}

	//删除节点

	if(!NodeToDelete)
	{
		delete NodeToDelete;
		NodeToDelete = NULL;
	}
	return true;

}

template<class T>  bool BlackRedTree<T>::LRb_AfterInsert(BlackRedNode<T>* Node)
{
	OutMsg("LRb_AfterInsert");
	BlackRedNode<T>* PNode,*GNode;
	PNode = Node->Parent;
	GNode = PNode->Parent;
	if(PNode!= GNode->Left || Node!= PNode->Right || (GNode->Right!=NULL && GNode->Right->Color!=BLACK))
	{
		cout<<"插入节点之后,不是LRb类型"<<endl;
		return true;
	}
	//根据数据结构上给出的算法进行旋转
	BlackRedNode<T>* NewNode,*NodeToDelete; 
	NewNode = new BlackRedNode<T>(GNode->Data,RED);
	NodeToDelete = PNode ->Right;

	NewNode->Left = NodeToDelete->Right;
	NewNode->Right = GNode->Right;
	
	GNode->Left->Right = NodeToDelete->Left;
	GNode->Right = NewNode;
	GNode->Data = NodeToDelete->Data;

	PNode->Right = NodeToDelete ->Left;

	//调整父节点
	if(NewNode)
	{
		if(NewNode->Left)
		{
			NewNode->Left->Parent = NewNode;
		}
		if(NewNode->Right)
		{
			NewNode->Right->Parent = NewNode;
		}
	}
	if(GNode->Left->Right)
	{
		GNode->Left->Right->Parent = GNode;
	}
	if(GNode->Right)
	{
		GNode->Right->Parent = GNode;
	}
	if(PNode->Right)
	{
		PNode->Right->Parent = PNode;
	}

	//删除节点
	if(!NodeToDelete)
	{
		delete NodeToDelete;
		NodeToDelete = 0;
	}
	return true;
}

template<class T> bool BlackRedTree<T>::RRb_AfterInsert(BlackRedNode<T>* Node)
{
	OutMsg("RRb_AfterInsert");
	BlackRedNode<T>* PNode,*GNode;
	PNode = Node->Parent;
	GNode = PNode->Parent;
	if(PNode!= GNode->Right || Node!= PNode->Right || (GNode->Left!=NULL && GNode->Left->Color!=BLACK))
	{
		cout<<"插入节点之后,不是RRb类型"<<endl;
		return true;
	}
	//进行旋转
	BlackRedNode<T>* NewNode,*NodeToDelete;
	NewNode = new BlackRedNode<T>(GNode->Data,RED);
	NodeToDelete = PNode;

	NewNode->Left = GNode->Left;
	NewNode->Right = NodeToDelete->Left;
	
	GNode->Data = NodeToDelete->Data;
	GNode->Left = NewNode;
	GNode->Right = NodeToDelete->Right;

	//调整父节点
	if(NewNode)
	{
		if(NewNode->Left)
		{
			NewNode->Left->Parent = NewNode;
		}
		if(NewNode->Right)
		{
			NewNode->Right->Parent = NewNode;
		}
	}
	if(GNode->Left)
	{
		GNode->Left->Parent = GNode;
	}
	if(GNode->Right)
	{
		GNode->Right->Parent = GNode;
	}
	//删除节点
	if(!NodeToDelete)
	{
		delete NodeToDelete;
		NodeToDelete = 0;
	}
	return true;

}

template<class T> bool BlackRedTree<T>::RLb_AfterInsert(BlackRedNode<T>* Node)
{
	OutMsg("RLb_AfterInsert");
	BlackRedNode<T>* PNode,*GNode;
	PNode = Node->Parent;
	GNode = PNode->Parent;
	if(PNode!= GNode->Right || Node!= PNode->Left || (GNode->Left!=NULL && GNode->Left->Color!=BLACK))
	{
		cout<<"插入节点之后,不是RLb类型"<<endl;
		return true;
	}
	//进行旋转
	BlackRedNode<T>* NewNode,*NodeToDelete;
	NewNode = new BlackRedNode<T>(GNode->Data,RED);
	NodeToDelete = PNode->Left;

	NewNode->Left = GNode->Left;
	NewNode->Right = NodeToDelete->Left;
	
	GNode->Data = NodeToDelete->Data;
	GNode->Left = NewNode;
	GNode->Right->Left = NodeToDelete->Right;

	//调整父节点
	if(NewNode)
	{
		if(NewNode->Left)
		{
			NewNode->Left->Parent = NewNode;
		}
		if(NewNode->Right)
		{
			NewNode->Right->Parent = NewNode;
		}
	}
	if(GNode->Left)
	{
		GNode->Left->Parent = GNode;
	}
	if(GNode->Right->Left)
	{
		GNode->Right->Left->Parent = GNode;
	}
	//删除节点
	if(!NodeToDelete)
	{
		delete NodeToDelete;
		NodeToDelete = 0;
	}
	return true;
}

template <class T> void BlackRedTree<T>::PrintTree(BlackRedNode<T> *t,int layer) const{
    if(t == NULL ) return;
	if(t->Right) PrintTree(t->Right,layer+1);
    for(int i =0;i<layer;i++) cout<<"  ";
	cout<<t->Data<<":"<<t->Color<<endl;
	if(t->Left) PrintTree(t->Left,layer+1);
}


#endif


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值