红黑树的实现源码(C语言版)

不多说啥了,这里不讲理论,需要的可以自己去看书(如算法导论等),就给出一份实现代码,供有需要的人参考之用,前后写了好久,参考的是linux内核中红黑树的实现代码:http://lxr.linux.no/linux/lib/rbtree.c

实现的操作有:插入,查找,删除.


/*-----------------------------------------------------------

RB-Tree的插入和删除操作的实现算法

参考资料:

1)<<Introductiontoalgorithm>>

2)http://lxr.linux.no/linux/lib/rbtree.c



作者:http://www.cppblog.com/converse/

您可以自由的传播,修改这份代码,转载处请注明原作者



红黑树的几个性质:

1)每个结点只有红和黑两种颜色

2)根结点是黑色的

3)空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的空节点)。

4)如果一个结点是红色的,那么它的左右两个子结点的颜色是黑色的

5)对于每个结点而言,从这个结点到叶子结点的任何路径上的黑色结点

的数目相同

-------------------------------------------------------------*/



#include<stdio.h>

#include<stdlib.h>

#include<string.h>



typedefintkey_t;

typedefintdata_t;



typedefenumcolor_t

{

RED=0,

BLACK=1

}color_t;



typedefstructrb_node_t

{

structrb_node_t*left,*right,*parent;

key_tkey;

data_tdata;

color_tcolor;

}rb_node_t;



/*forwarddeclaration*/

rb_node_t*rb_insert(key_tkey,data_tdata,rb_node_t*root);

rb_node_t*rb_search(key_tkey,rb_node_t*root);

rb_node_t*rb_erase(key_tkey,rb_node_t*root);



intmain()

{

inti,count=900000;

key_tkey;

rb_node_t*root=NULL,*node=NULL;



srand(time(NULL));

for(i=1;i<count;++i)

{

key=rand()%count;

if((root=rb_insert(key,i,root)))

{

printf("[i=%d]insertkey%dsuccess!/n",i,key);

}

else

{

printf("[i=%d]insertkey%derror!/n",i,key);

exit(-1);

}



if((node=rb_search(key,root)))

{

printf("[i=%d]searchkey%dsuccess!/n",i,key);

}

else

{

printf("[i=%d]searchkey%derror!/n",i,key);

exit(-1);

}

if(!(i%10))

{

if((root=rb_erase(key,root)))

{

printf("[i=%d]erasekey%dsuccess/n",i,key);

}

else

{

printf("[i=%d]erasekey%derror/n",i,key);

}

}

}



return0;

}



staticrb_node_t*rb_new_node(key_tkey,data_tdata)

{

rb_node_t*node=(rb_node_t*)malloc(sizeof(structrb_node_t));



if(!node)

{

printf("mallocerror!/n");

exit(-1);

}

node->key=key,node->data=data;



returnnode;

}



/*-----------------------------------------------------------

|noderight

|//==>//

|arightnodey

|

|byab

-----------------------------------------------------------*/

staticrb_node_t*rb_rotate_left(rb_node_t*node,rb_node_t*root)

{

rb_node_t*right=node->right;



if((node->right=right->left))

{

right->left->parent=node;

}

right->left=node;



if((right->parent=node->parent))

{

if(node==node->parent->right)

{

node->parent->right=right;

}

else

{

node->parent->left=right;

}

}

else

{

root=right;

}

node->parent=right;



returnroot;

}



/*-----------------------------------------------------------

|nodeleft

|

|lefty==>anode

|

|abby

-----------------------------------------------------------*/

staticrb_node_t*rb_rotate_right(rb_node_t*node,rb_node_t*root)

{

rb_node_t*left=node->left;



if((node->left=left->right))

{

left->right->parent=node;

}

left->right=node;



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

{

if(node==node->parent->right)

{

node->parent->right=left;

}

else

{

node->parent->left=left;

}

}

else

{

root=left;

}

node->parent=left;



returnroot;

}



staticrb_node_t*rb_insert_rebalance(rb_node_t*node,rb_node_t*root)

{

rb_node_t*parent,*gparent,*uncle,*tmp;



while((parent=node->parent)&&parent->color==RED)

{

gparent=parent->parent;



if(parent==gparent->left)

{

uncle=gparent->right;

if(uncle&&uncle->color==RED)

{

uncle->color=BLACK;

parent->color=BLACK;

gparent->color=RED;

node=gparent;

}

else

{

if(parent->right==node)

{

root=rb_rotate_left(parent,root);

tmp=parent;

parent=node;

node=tmp;

}



parent->color=BLACK;

gparent->color=RED;

root=rb_rotate_right(gparent,root);

}

}

else

{

uncle=gparent->left;

if(uncle&&uncle->color==RED)

{

uncle->color=BLACK;

parent->color=BLACK;

gparent->color=RED;

node=gparent;

}

else

{

if(parent->left==node)

{

root=rb_rotate_right(parent,root);

tmp=parent;

parent=node;

node=tmp;

}



parent->color=BLACK;

gparent->color=RED;

root=rb_rotate_left(gparent,root);

}

}

}



root->color=BLACK;



returnroot;

}



staticrb_node_t*rb_erase_rebalance(rb_node_t*node,rb_node_t*parent,rb_node_t*root)

{

rb_node_t*other,*o_left,*o_right;



while((!node||node->color==BLACK)&&node!=root)

{

if(parent->left==node)

{

other=parent->right;

if(other->color==RED)

{

other->color=BLACK;

parent->color=RED;

root=rb_rotate_left(parent,root);

other=parent->right;

}

if((!other->left||other->left->color==BLACK)&&

(!other->right||other->right->color==BLACK))

{

other->color=RED;

node=parent;

parent=node->parent;

}

else

{

if(!other->right||other->right->color==BLACK)

{

if((o_left=other->left))

{

o_left->color=BLACK;

}

other->color=RED;

root=rb_rotate_right(other,root);

other=parent->right;

}

other->color=parent->color;

parent->color=BLACK;

if(other->right)

{

other->right->color=BLACK;

}

root=rb_rotate_left(parent,root);

node=root;

break;

}

}

else

{

other=parent->left;

if(other->color==RED)

{

other->color=BLACK;

parent->color=RED;

root=rb_rotate_right(parent,root);

other=parent->left;

}

if((!other->left||other->left->color==BLACK)&&

(!other->right||other->right->color==BLACK))

{

other->color=RED;

node=parent;

parent=node->parent;

}

else

{

if(!other->left||other->left->color==BLACK)

{

if((o_right=other->right))

{

o_right->color=BLACK;

}

other->color=RED;

root=rb_rotate_left(other,root);

other=parent->left;

}

other->color=parent->color;

parent->color=BLACK;

if(other->left)

{

other->left->color=BLACK;

}

root=rb_rotate_right(parent,root);

node=root;

break;

}

}

}



if(node)

{

node->color=BLACK;

}



returnroot;

}



staticrb_node_t*rb_search_auxiliary(key_tkey,rb_node_t*root,rb_node_t**save)

{

rb_node_t*node=root,*parent=NULL;

intret;



while(node)

{

parent=node;

ret=node->key-key;

if(0<ret)

{

node=node->left;

}

elseif(0>ret)

{

node=node->right;

}

else

{

returnnode;

}

}



if(save)

{

*save=parent;

}



returnNULL;

}



rb_node_t*rb_insert(key_tkey,data_tdata,rb_node_t*root)

{

rb_node_t*parent=NULL,*node;



parent=NULL;

if((node=rb_search_auxiliary(key,root,&parent)))

{

returnroot;

}



node=rb_new_node(key,data);

node->parent=parent;

node->left=node->right=NULL;

node->color=RED;



if(parent)

{

if(parent->key>key)

{

parent->left=node;

}

else

{

parent->right=node;

}

}

else

{

root=node;

}



returnrb_insert_rebalance(node,root);

}



rb_node_t*rb_search(key_tkey,rb_node_t*root)

{

returnrb_search_auxiliary(key,root,NULL);

}



rb_node_t*rb_erase(key_tkey,rb_node_t*root)

{

rb_node_t*child,*parent,*old,*left,*node;

color_tcolor;



if(!(node=rb_search_auxiliary(key,root,NULL)))

{

printf("key%disnotexist!/n");

returnroot;

}



old=node;



if(node->left&&node->right)

{

node=node->right;

while((left=node->left)!=NULL)

{

node=left;

}

child=node->right;

parent=node->parent;

color=node->color;



if(child)

{

child->parent=parent;

}

if(parent)

{

if(parent->left==node)

{

parent->left=child;

}

else

{

parent->right=child;

}

}

else

{

root=child;

}



if(node->parent==old)

{

parent=node;

}



node->parent=old->parent;

node->color=old->color;

node->right=old->right;

node->left=old->left;



if(old->parent)

{

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

{

old->parent->left=node;

}

else

{

old->parent->right=node;

}

}

else

{

root=node;

}



old->left->parent=node;

if(old->right)

{

old->right->parent=node;

}

}

else

{

if(!node->left)

{

child=node->right;

}

elseif(!node->right)

{

child=node->left;

}

parent=node->parent;

color=node->color;



if(child)

{

child->parent=parent;

}

if(parent)

{

if(parent->left==node)

{

parent->left=child;

}

else

{

parent->right=child;

}

}

else

{

root=child;

}

}



free(old);



if(color==BLACK)

{

root=rb_erase_rebalance(child,parent,root);

}



returnroot;

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值