#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;
}