用c语言实现红黑树(依据算法导论上的方法)

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

    > File Name: RBT.h

    > Author: TimeFly

    > Mail:
[email protected] 

    > Created Time: 2014年08月06日 星期三 20时27分00秒

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

#ifndef RBT_H

#define RBT_H

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef char* ElemType;

#define ELEMTACITLY NULL //通配类型的默认值

typedef int Color;

#define RED 1

#define BLACK -1

typedef int bool;

#define true 1

#define false 0

typedef struct RBNode

{

Color color;

ElemType data;

struct RBNode *parent

struct RBNode *left;

struct RBNode *right;

}RBNode;

typedef struct RBTree

{

RBNode *Root;

RBNode *NIL;

int NodeSize;

}RBTree;

/***********************所有的函数声明**********************************/

RBTree* CreativeRBTree();

void Left-Rotate(RBTree* T,RBNode* x);

void Right-Rotate(RBTree* T,RBNode* x);

void RB_Insert(RBTree* ,RBNode* x);

bool RBNode_Less(RBNode *RBN_a,RBNode *RBN_b);

void RB_Insert_Fixup(RBTree* T,RBNode* x);

void RB_Trans_Plant(RBTree *T,RBNode *u,RBNode *v);

RBNode* RB_Tree_Min(RBTree *T,RBNode *z);

void RB_Destroy_Node(RBNode *z);

void RB_Destroy_Child_Tree(RBNode *T,RBNode *z);

void RB_Delete_Node(RBTree *T,RBNode *z);

void RB_Delete_Fixup(RBTree *T,RBNode *z);

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

//创建一颗空的红黑树

RBTree* CreativeRBTree()

{

RBTree* T = (RBTree*)malloc(sizeof(RBTree));

assert(T != NULL);

T->NIL = (RBNode*)malloc(sizeof(RBNode));

assert(T->NIL != NULL);

T->NIL->color = BLACK;

T->NIL->data = ELEMTACITLY;

T->NIL->parent = NULL;

T->NIL->left = NULL;

T->NIL->right = NULL;

T->Root = T->NIL;

return T;

}

//左旋转

void Left_Rotate(RBTree *T,RBNode *x)

{

if(x->right == T->NIL)

{

printf(“x have not a right child can not be left-rotate\n”);

exit(1);

}

RBNode *y = x->right;

x->right = y->left;

if(y->left != T->NIL)

{

y->left->parent = x;

}//到这一步搞定x的右孩子的左孩子

y->parent = x->parent;

if(x->parent == T->NIL)//防止x是根节点

{

T->Root = y;

}

else if(x->parent->right = x)

{

x->parent->right = y;

}

else

{

x->parent->left = y;

}//到这一步搞定x的父节点

y->left = x;

x->parent = y;

}

//右旋转

void Right_Rotate(RBTree *T,RBNode *x)

{

if(x->left == T->NIL)

{

printf(“x have not a left child can not be right-rotate\n”);

exit(1);

}

RBNode *y = x->left;

x->left = y->right;

if(y->right != T->NIL)

{

y->right->parent = x;

}//搞定x的左孩子的右孩子

y->parent = x->parent;

if(x->parent == T->NIL)

{

T->Root = y;

}//防止原本的x是根节点

else if(x->parent->right == x)

{

x->parent->right = y;

}

else

{

x->parent->left = y;

}//到这里把x的父节点搞定了

y->right = x;

x->parent = y;

}

//为了通用性,对于具体的红黑树,使用不同的比较函数

bool RBNode_Less(RBNode *RBN_a,RBNode *RBN_b)

{

return strcmp(RBN_a->data,RBN_b->data) < 0;

}

void RB_Insert(RBTree *T,RBNode *x,bool less(RBNode*,RBNode*));

{

RBNode *par = T->NIL;

RBNode *Temp = T->Root;

while(Temp != T->NIL)

{

par = Temp;

if(less(x,Temp))

{

Temp = Temp->left;

}

else

{

Temp = Temp->right;

}

}

x->parent = par;

if(x->parent == T->NIL)

{

T->Root = x;

}

else if(less(x,par))

{

par->left = x;

}

else

{

par->right = x;

}

x->left = T->NIL;

x->right = T->NIL;

x->color = RED;

//上面这些都是最基本的插入,很简单,唯一要注意的是,当树是空树的情况。

//这个RB_Insert_Fixup才是重头戏

RB_Insert_Fixup(T,x);

}

//插入节点成功后,调用该函数,保持红黑树性质不变

void RB_Insert_Fixup(RBTree *T,RBNode *x)

{

RBNode *uncle = NULL;//这个是父节点的兄弟节点,称呼它位叔叔节点

while(x->parent->color == RED)//如果父节点不是红节点,当然就没那么多事情了。

{

if(x->parent == x->parent->parent->left)

{

uncle = x->parent->parent->right;

if(uncle->color == RED)//这里处理的是情况1

{

x->parent->color = BLACK;

uncle->color = BLACK;

x->parent->parent->color = RED;

x = x->parent->parent;

}

else

{

if(x == x->parent->right)//在情况2的条件下,把情况2转化为情况3

{

x = x->parent;

Left_Rotate(T,x);

}

//然后下面三条处理情况3

x->parent->color = BLACK;

x->parent->parent->color = RED;

Right_Rotate(T,x);

}

}

else //这个else和上面的仅仅是方向不同,其余的一样

{

uncle = x->parent->parent->left;

if(uncle->color == RED)

{

x->parent->color = BLACK;

uncle->color = BLACK;

x->parent->parent = RED;

x = x->parent->parent;

}

else

{

if(x == x->parent->left)

{

x = x->parent;

Right_Rotate(T,x);

}

x->parent->color = BLACK;

x->parent->parent->color = RED;

Left_Rotate(T,x);

}

}

}

//如果是情况3退出循环,当然什么也不必做,但是如果是情况1退出的循环,就存在根节点被着色的情况,所以添加该语句,不管以什么情况结尾都不会错了。

T->Root->color = BLACK;

}

//找寻从该节点开始最左端的节点

RBNode *RB_Tree_Min(RBTree *T,RBNode *z)

{

RBNode *Temp = z;

while(Temp->left != T->NIL)

{

Temp = Temp->left;

}

return Temp;

}

//把树中的节点u用节点v替换,但是这个函数不提供释放空间的功能

void RB_Trans_Plant(RBTree *T,RBNode *u,RBNode *v)

{

if(u->parent == T->Root)

{

T->Root = v;

}

else if(u->parent->right == u)

{

u->parent->right = v;

}

else

{

u->parent->left = v;

}

v->parent = u->parent;

}

//销毁一个节点,并释放其占用的空间

void RB_Destroy_Node(RBNode *z)

{

free(z->data);

free(z);

}

//销毁树T上从z节点开始所形成的子树

void RB_Destroy_Child_Tree(RBTree *T,RBNode *z)

{

if(z->left != T->NIL)

{

RB_Destroy_Child_Tree(T,z->left);

}

if(z->right != T->NIL)

{

RB_Destroy_Child_Tree(T,z->right);

}

RB_Destroy_Node(z);

}

//删除树T上的节点z,并且释放节点z的空间

void RB_Delete_Node(RBTree *T,RBNode *z)

{

RBNode *des = z;

Color origin_color = des->color;

RBNode *replace = NULL;

if(z->left == T->NIL)

{

replace = z->right;

RB_Trans_Plant(T,z,replace);

}

else if(z->right == T->NIL)

{

replace = z->left;

RB_Trans_Plant(T,z,replace);

}

else

{

des = RB_Tree_Min(T,z->right);

origin_color = des->color;

replace = des->right;

if(des->parent == z)

{

replace->parent = des;

}

else

{

RB_Trans_Plant(T,des,replace);

des->right = z->right;

des->right->parent->des;

}

RB_Trans_Plant(T,z,des);

des->left = z->left;

des->left->parent->des;

des.color = z.color;

}

if(origin_color == BLACK)

{

RB_Delete_Fixup(T,replace);

}

RB_Destroy_Node(z);

T->NIL->parent = NULL;//这句是我擅自添加的,与《算法导论》不同,因为在删除过程中NIL的parent节点可能会被修改,因为这是在特殊情况下需要使用的,在修改过后,不去修改回来,虽然不会影响到算法,但是我觉得在用完后还是纠正回指向空指针,比较好。

}

//删除后,调用该函数保存红黑树性质不变

void RB_Delete_Fixup(RBTree *T,RBNode *z)

{

RBNode *Temp = z;

RBNode *Brother = NULL;

while(Temp != T->Root && Temp == BLACK)

{

if(Temp == Temp->parent->left)

{

Brother = Temp->parent->right;

//case 1

if(Brother->color == RED)

{

Brother->color = BLACK;

Temp->parent->color = RED;

Left_Rotate(T,Temp_>parent);

Brother = Temp->parent->right;

}

//case 2

if(Brother->left == BLACK && Brother->right == BLACK)

{

Brother->color = RED;

Temp = Temp->parent;

}

else 

{

//case 3

if(Brother->right->color == BLACK)

{

Brother->left->color = BLACK;

Brother->color = RED;

Right_Rotate(T,Brother);

Brother = Temp->parent->right;

}

//case 4

Brother->color = Temp->parent->color;

Temp->parent->color = BLACK;

Brother->right->color = BLACK;

Left_Rotate(T,Temp->parent);

Temp = T->Root;

}

}

else

{

Brother = Temp->parent->left;

//case 1

if(Brother->color == RED)

{

Brother->color = BLACK;

Temp->parent->color = RED;

Right_Rotate(T,Temp->parent);

Brother = Temp->parent->left;

}

//case 2

if(Brother->right == BLACK && Brother->left == BLACK)

{

Brother->color = RED;

Temp = Temp->parent;

}

else

{

//case 3

if(Brother->left->color == BLACK)

{

Brother->right->color = BLACK;

Brother->color = RED;

Left_Rotate(T,Brother);

Brother = Temp->parent->left;

}

//case 4

Brother->color = Temp->parent->color;

Temp->parent->color = BLACK;

Brother->left->color = BLACK;

Right_Rotate(T,Brother);

Temp = T->Root;

}

}

}

Temp->color = BLACK;

}

void RB_Destroy_Tree(RBTree *T)

{

RB_Destroy_Child_Tree(T,T->Root);

free(T->NIL);

}

#endif

点赞