红黑树代码实现

#include<time.h>
#include<stdio.h>
#include<malloc.h>
#include<stdbool.h>
typedef struct Balance_Tree
{
	int id;
	void* data;
	int color;
	struct Balance_Tree* parent;
	struct Balance_Tree* left;
	struct Balance_Tree* right;
}Balance_Tree;
enum RB_COLOR
{
	BLACK,
	RED
};
//创造节点
static Balance_Tree* Create_Node(int id,void*data)
{
	Balance_Tree* Node = (Balance_Tree*)malloc(sizeof(Balance_Tree));
	if (Node == NULL)
		return NULL;
	Node->id = id;
	Node->data = data;
	Node->color = RED;
	Node->parent = NULL;
	Node->left = NULL;
	Node->right = NULL;
	return Node;
}
//获取节点颜色
static inline int GetNode_Color(Balance_Tree*Node)
{
	return Node!=NULL ? Node->color : BLACK;
}
//右旋
static inline void L_L(Balance_Tree*Node_Left_Son, Balance_Tree*Node)
{
	Balance_Tree* Node_parent = Node->parent;
	Balance_Tree* Node_Left_Son_right = Node_Left_Son->right;
	Node->parent = Node_Left_Son;
	Node_Left_Son->right = Node;
	Node->left = Node_Left_Son_right;
	if (Node_Left_Son_right !=NULL)
	{
		Node_Left_Son_right->parent = Node;
	}
	if (Node_parent !=NULL)
	{
		if (Node_parent->left == Node)
			Node_parent->left = Node_Left_Son;
		else
			Node_parent->right = Node_Left_Son;
	}
	Node_Left_Son->parent = Node_parent;
}
//左旋
static inline void R_R(Balance_Tree*Node, Balance_Tree*Node_Right_Son)
{
	Balance_Tree* Node_parent = Node->parent;
	Balance_Tree* Node_Right_Son_left = Node_Right_Son->left;
	Node->parent = Node_Right_Son;
	Node_Right_Son->left = Node;
	Node->right = Node_Right_Son_left;
	if (Node_Right_Son_left !=NULL)
	{
		Node_Right_Son_left->parent = Node;
	}
	if (Node_parent !=NULL)
	{
		if (Node_parent->left == Node)
			Node_parent->left = Node_Right_Son;
		else
			Node_parent->right = Node_Right_Son;
	}
	Node_Right_Son->parent = Node_parent;
}
//调整方法
static inline void  Opt_R_B(Balance_Tree* Grand_parent, Balance_Tree* parent, Balance_Tree* Uncle)
{
	Grand_parent->color = RED;
	parent->color = BLACK;
	Uncle->color = BLACK;
}
static inline void Opt_LL(Balance_Tree* Grand_parent, Balance_Tree* parent)
{
	Grand_parent->color = RED;
	parent->color = BLACK;
	L_L(parent,Grand_parent);
}
static inline void Opt_RR(Balance_Tree* Grand_parent, Balance_Tree* parent)
{
	Grand_parent->color = RED;
	parent->color = BLACK;
	R_R(Grand_parent,parent);
}
static inline void Opt_LR(Balance_Tree* Grand_parent, Balance_Tree* parent, Balance_Tree*Node)
{
	Grand_parent->color = RED;
	R_R(parent,Node);
	Node->color = BLACK;
	L_L(Node,Grand_parent);
}
static inline void Opt_RL(Balance_Tree* Grand_parent, Balance_Tree* parent, Balance_Tree*Node)
{
	Grand_parent->color = RED;
	L_L(Node, parent);
	Node->color = BLACK;
	R_R(Grand_parent,Node);
}
//调整树节点
static Balance_Tree* Adjust_Tree(Balance_Tree*Node)
{
	Balance_Tree* parent = NULL;
	Balance_Tree* Uncle = NULL;
	Balance_Tree* Grand_parent = NULL;
	do{
	     parent = Node->parent;
		 Grand_parent = parent->parent;
		if (Grand_parent->left == parent)
			Uncle = Grand_parent->right;
		else
			Uncle = Grand_parent->left;
	//判断是否为父叔为红
	 if (GetNode_Color(Uncle)==RED)
	 {//如果是父叔双红就变黑
		 Opt_R_B(Grand_parent, parent, Uncle);
		 Node = Grand_parent;
		 if (GetNode_Color(Grand_parent->parent) == BLACK)
			 return Grand_parent;
	 }
	 else
		 break;
	}while (true);
	//进行旋转调整
	if (Grand_parent->left == parent)
	{//L
		if (parent->left == Node)
		{//L+L
			Opt_LL(Grand_parent, parent);
		    Grand_parent = parent;
		}
		else
		{//L+R
			Opt_LR(Grand_parent, parent, Node);
		    Grand_parent = Node;
		}
	}
	else
	{//R
		if (parent->right == Node)
		{//R+R
			 Opt_RR(Grand_parent, parent);
			 Grand_parent = parent;
		}
		else
		{//R+L
			Opt_RL(Grand_parent, parent, Node);
			Grand_parent = Node;
		}
	}
	return Grand_parent;
}
//增加树节点
extern bool Add_Node(Balance_Tree**Tree,int id,void *data)
{
	Balance_Tree* Add = Create_Node(id, data);
	if (Add == NULL)
		return false;
	if (*Tree==NULL)
	{
		*Tree = Add;
		(*Tree)->color = BLACK;
		return true;
	}
	Balance_Tree* Temp = *Tree;
	while (true)
	{
		if (Temp->id==id)
		{
			free(Add);
			return false;
		}
		else if (Temp->id>id)
		{
			if (Temp->left == NULL)
			{
				Temp->left = Add;
				break;
			}
			Temp = Temp->left;
		}
		else
		{
			if (Temp->right==NULL)
			{
				Temp->right = Add;
				break;
			}
			Temp = Temp->right;
		}
	}	
	Add->parent = Temp;
	//如果父亲节点是红色就触发红黑调整
	if(GetNode_Color(Temp)==RED)
	{
		Temp = Adjust_Tree(Add);
		//判断根节点是否发生变化
		if (Temp->parent == NULL)
		{
			*Tree = Temp;
			(*Tree)->color = BLACK;
		}
	}
	return true;
}
//查找树节点
extern Balance_Tree* Find_Node(Balance_Tree*Node,int id)
{
	while (Node!=NULL)
	{
		if (Node->id==id)
			return Node;		
		else if (Node->id>id)		
			Node = Node->left;		
		else	
			Node = Node->right;	
	}
	return Node;
}
static Balance_Tree* Right_Node(Balance_Tree*Node)
{
	while (Node->right != NULL)
	{
		Node = Node->right;
	}
	return Node;
}
static inline void Copy_Node(Balance_Tree*Node1,Balance_Tree*Node2)
{
	Node1->id = Node2->id;
	Node1->data = Node2->data;
}
//处理旋转的黑色节点
static Balance_Tree* Del_Exchange(Balance_Tree*parent, Balance_Tree*Uncle)
{
	if (GetNode_Color(Uncle) == RED)
	{//叔叔为红
		Balance_Tree* Temp = NULL;
		Uncle->color = BLACK;
		if (parent->left==Uncle)
		{//确定叔叔节点的位置
			Temp = Uncle->right;
			Temp->color = RED;
			L_L(Uncle,parent);
			if (GetNode_Color(Temp->left) == RED || GetNode_Color(Temp->right) == RED)
			{//判断侄子是否存在子节点
				if (GetNode_Color(Temp->left) == BLACK)
				{//判断侄子节点是否只存在一个红色节点
					R_R(Temp, Temp->right);
					Temp->color = BLACK;
					Temp = Temp->parent;
				}
				else
					Temp->left->color = BLACK;
				L_L(Temp,parent);
			}
	    }
		else
		{
			Temp = Uncle->left;
			Temp->color = RED;
			R_R(parent,Uncle);
			if (GetNode_Color(Temp->left) == RED || GetNode_Color(Temp->right) == RED)
			{//判断侄子是否存在子节点
				if (GetNode_Color(Temp->right) == BLACK)
				{//判断侄子节点是否只存在一个红色节点
					L_L(Temp->left, Temp);
					Temp->color = BLACK;
					Temp = Temp->parent;
				}
				else
					Temp->right->color = BLACK;
				R_R(parent,Temp);
			}
		}
	}
	else
	{//叔叔为黑
		int color = parent->color;//父亲节点可能为红色,记住父亲节点的颜色
		parent->color = BLACK;
		if (parent->left == Uncle)
		{//确定叔叔节点的位置
			if (GetNode_Color(Uncle->left) == BLACK)
			{//判断侄子节点是否只存在一个红色节点
				Uncle->right->color = BLACK;
				R_R(Uncle, Uncle->right);
				Uncle = parent->left;
			}
			else
				Uncle->left->color = BLACK;
			L_L(Uncle,parent);
		}
		else
		{
			if (GetNode_Color(Uncle->right) == BLACK)
			{//判断侄子节点是否只存在一个红色节点
				Uncle->left->color = BLACK;
				L_L(Uncle->left, Uncle);
				Uncle = parent->right;
			}
			else
				Uncle->right->color = BLACK;
			R_R(parent,Uncle);
		}
		//恢复父亲节点的颜色
		Uncle->color = color;
	}
	return Uncle;
}
//删除树节点
extern bool Del_Node(Balance_Tree**Node,int id)
{//对删除的各个状态进行细分处理
	Balance_Tree* Del = Find_Node(*Node,id);
	if (Del == NULL)
		return false;
	Balance_Tree* parent = NULL;
	Balance_Tree* Uncle = NULL;
	if (Del->left!=NULL&&Del->right!=NULL)
	{//双孩子
		Balance_Tree* replace = Right_Node(Del->left);
		Copy_Node(Del,replace);
		Del = replace;
	}
	if (Del->left!=NULL||Del->right!=NULL)
	{//单孩子
		Balance_Tree* replace = NULL;
		if (Del->left == NULL)
		{//判断哪个孩子不为空,不为空的孩子必为红色节点
			replace = Del->right;
			Del->right = NULL;
		}
		else
		{
			replace = Del->left;
			Del->left = NULL;
		}
		Copy_Node(Del,replace);
		parent = Del;
		Del = replace;
	}
	else
	{//没有孩子
		parent = Del->parent;
		if (parent == NULL)
		{//根节点
			*Node = NULL;
		}
		else
		{//非根节点
			if (parent->left==Del)
			{//获取叔叔节点
				Uncle = parent->right;
				parent->left = NULL;
			}
			else
			{
				Uncle = parent->left;
				parent->right = NULL;
			}
			if (GetNode_Color(Del)==BLACK)
			{//判断删除的叶节点是否为黑色节点
				Balance_Tree* Temp = NULL;
				while (GetNode_Color(parent)==BLACK&&GetNode_Color(Uncle)==BLACK&& GetNode_Color(Uncle->left)==BLACK&&GetNode_Color(Uncle->right)==BLACK)
				{//对父黑兄黑双侄黑处理颜色不需要旋转节点
					Temp = parent;
					Uncle->color = RED;
					//判断是否到达根节点
					if (parent->parent == NULL)
						return true;
					else//向上递归处理
						parent = parent->parent;
					if (parent->left == Temp)
						Uncle = parent->right;
					else
						Uncle = parent->left;
				}
				if (GetNode_Color(parent) == RED &&GetNode_Color(Uncle) == BLACK && GetNode_Color(Uncle->left) == BLACK && GetNode_Color(Uncle->right) == BLACK)
				{//对父红兄黑双侄黑处理变换不需要旋转节点
					parent->color = BLACK;
					Uncle->color = RED;
				}
				else
				{//需要节点旋转变化的节点方法
					parent = Del_Exchange(parent, Uncle);
				}
			}//如果为红色节点直接删除即可,不做任何处理
		}
	}
	free(Del);
	if (parent!=NULL&&parent->parent == NULL)
	{//判断当前的节点处理的时候是否涉及到根节点
		*Node = parent;
		parent->color = BLACK;
	}
	return true;
}
//利用后续遍历销毁树
extern void Destroy_Tree(Balance_Tree*Node)
{
	if (Node == NULL)
		return;
	Destroy_Tree(Node->left);
	Destroy_Tree(Node->right);
	free(Node);
}
extern void Find(Balance_Tree*Node)
{
	if (Node == NULL)
		return;
	Find(Node->left);
	printf(Node->color==RED?"%d   RED\n":"%d BLACK\n", Node->id);
	Find(Node->right);
}
int main()
{
	Balance_Tree* Tree = NULL;
	srand(time(NULL));
	clock_t t = clock();
	for (int i=0;i<10000000;i++)
	{
		Add_Node(&Tree,i, NULL);
    }
	printf("%dms\n",clock()-t);
	t = clock();
	for (int i = 0; i < 10000000; i++)
	{
		Del_Node(&Tree,i);
	}
	printf("%dms\n", clock() - t);
	Find(Tree);
	return 0;
}

 

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值