您的位置:首页 > 其它

红黑树算法实现(算法导论)

2010-04-14 15:40 274 查看
/*******************************************
Module: redblacktree.h
Notices: Copyrigjt (c) 2007-2010 ls
*******************************************/
#ifndef _REDBLACKTREE_H
#define _REDBLACKTREE_H

#ifdef __cplusplus
extern "C"{
#endif

#ifndef u_char
#define u_char unsigned char
#endif

#ifndef NULL
#define NULL 0
#endif

typedef struct rb_node_s{
u_char color;
int key;
void *val;

struct rb_node_s *left;
struct rb_node_s *right;
struct rb_node_s *parent;
}rb_node_t;

typedef struct rb_tree_s{
rb_node_t *root;
rb_node_t *nil;
}rb_tree_t;

#define RBT_RED(node)                        ((node)->color=1)
#define RBT_BLACK(node)                    ((node)->color=0)
#define RBT_IS_RED(node)                    ((node)->color)
#define RBT_IS_BLACK(node)                (!(RBT_IS_RED(node)))
#define RBT_NIL_INIT(node)                RBT_BLACK(node)
#define RBT_COPY_COLOR(dst,src)    ((dst)->color=(src)->color)

#define LT(a,b) ((a)<(b))
#define EQ(a,b) ((a)==(b))

void                rbt_init(rb_tree_t *tree,rb_node_t *nil);
int                    rbt_insert(rb_tree_t *t,rb_node_t *z);
rb_node_t*        rbt_delete(rb_tree_t *t,rb_node_t *z);
rb_node_t*         rbt_find(rb_tree_t *t,int key);
void                rbt_in_order(rb_tree_t *t,void (*RbtOrderCallBack)(rb_node_t *));
rb_node_t*        rbt_min(rb_tree_t *t);
rb_node_t*        rbt_max(rb_tree_t *t);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* _REDBLACKTREE_H */


/*******************************************
Module: redblacktree.c
Notices: Copyrigjt (c) 2007-2010 ls
*******************************************/
#include "redblacktree.h"

static void rbt_rotate_left(rb_tree_t *t,rb_node_t *x)
{
rb_node_t *y=x->right;

x->right=y->left;
if(y->left!=t->nil){
y->left->parent=x;
}
y->parent=x->parent;
if(x->parent!=t->nil){
if(x==x->parent->left){
x->parent->left=y;
}
else{
x->parent->right=y;
}
}
else{
t->root=y;
}
y->left=x;
x->parent=y;
}

static void rbt_rotate_right(rb_tree_t *t,rb_node_t *x)
{
rb_node_t *y=x->left;

x->left=y->right;
if(y->right!=t->nil){
y->right->parent=x;
}
y->parent=x->parent;
if(x->parent!=t->nil){
if(x==x->parent->right){
x->parent->right=y;
}
else{
x->parent->left=y;
}
}
else{
t->root=y;
}
}

static void rbt_insert_fixup(rb_tree_t *t,rb_node_t *z)
{
rb_node_t *y;
/* check red-black properties */
while((z!=t->root)&&RBT_IS_RED(z->parent)){
/* have a violation */
if(z->parent==z->parent->parent->left){
y=z->parent->parent->right;
if(RBT_IS_RED(y)){
/* uncle is RED */
RBT_BLACK(z->parent);
RBT_BLACK(y);
RBT_RED(z->parent->parent);
z=z->parent->parent;
}
else{
/* uncle is BLACK */
if(z==z->parent->right){
/* make z a left child */
z=z->parent;
rbt_rotate_left(t,z);
}
/* recolor and rotate */
RBT_BLACK(z->parent);
RBT_RED(z->parent->parent);
rbt_rotate_right(t,z->parent->parent);
}
}
else{
/* mirror image of above code */
y=z->parent->parent->left;
if(RBT_IS_RED(y)){
/* uncle is RED */
RBT_BLACK(z->parent);
RBT_BLACK(y);
RBT_RED(z->parent->parent);
z=z->parent->parent;
}
else{
/* uncle is BLACK */
if(z==z->parent->left){
z=z->parent;
rbt_rotate_right(t,z);
}
RBT_BLACK(z->parent);
RBT_RED(z->parent->parent);
rbt_rotate_left(t,z->parent->parent);
}
}
}
RBT_BLACK(t->root);
}

static void rbt_delete_fixup(rb_tree_t *t,rb_node_t *x)
{
rb_node_t *w;

while((x!=t->root)&&RBT_IS_BLACK(x)){
if(x==x->parent->left){
w=x->parent->right;
if(RBT_IS_RED(w)){
RBT_BLACK(w);
RBT_RED(x->parent);
rbt_rotate_left(t,x->parent);
w=x->parent->right;
}
if(RBT_IS_BLACK(w->left)&&(RBT_IS_BLACK(w->right))){
RBT_RED(w);
x=x->parent;
}
else{
if(RBT_IS_BLACK(w->right)){
RBT_BLACK(w->left);
RBT_RED(w);
rbt_rotate_right(t,w);
w=x->parent->right;
}
RBT_COPY_COLOR(w,x->parent);//w->color=x->parent->color;

RBT_BLACK(x->parent);
RBT_BLACK(w->right);
rbt_rotate_left(t,x->parent);
x=t->root;
}
}
else{
/* clause with 'right' and left exchanged */
w=x->parent->left;
if(RBT_IS_RED(w)){
RBT_BLACK(w);
RBT_RED(x->parent);
rbt_rotate_right(t,x->parent);
w=x->parent->left;
}
if((RBT_IS_BLACK(w->right))&&(RBT_IS_BLACK(w->left))){
RBT_RED(w);
x=x->parent;
}
else{
if(RBT_IS_BLACK(w->left)){
RBT_BLACK(w->right);
RBT_RED(w);
rbt_rotate_left(t,w);
w=x->parent->left;
}
RBT_COPY_COLOR(w,x->parent);//w->color=x->parent->color;

RBT_BLACK(x->parent);
RBT_BLACK(w->left);
rbt_rotate_right(t,x->parent);
x=t->root;
}
}
}
RBT_BLACK(x);
}

static void rbt_in_order_internal(rb_tree_t *t,rb_node_t *n,void (*RbtOrderCallBack)(rb_node_t *))
{
if(n==t->nil){
return;
}
rbt_in_order_internal(t,n->left,RbtOrderCallBack);
RbtOrderCallBack(n);
rbt_in_order_internal(t,n->right,RbtOrderCallBack);
}

void rbt_init(rb_tree_t *tree,rb_node_t *nil)
{
RBT_NIL_INIT(nil);
tree->nil=nil;
tree->root=nil;
}

int rbt_insert(rb_tree_t *t,rb_node_t *z)
{
rb_node_t *y,*x;

y=t->nil;
x=t->root;

while(x!=t->nil){
if(EQ(z->key,x->key)){
return(1);
}
y=x;
x=LT(z->key,x->key)?x->left:x->right;
}
z->parent=y;
if(y!=t->nil){
if(LT(z->key,y->key)){
y->left=z;
}
else{
y->right=z;
}
}
else{
t->root=z;
}
z->left=t->nil;
z->right=t->nil;
RBT_RED(z);

rbt_insert_fixup(t,z);

return(0);
}

rb_node_t *rbt_delete(rb_tree_t *t,rb_node_t *z)
{
rb_node_t *x,*y;

if((z->left==t->nil)||(z->right==t->nil)){
y=z; /* y has a nil node as a child */
}
else{
y=z->right; /* find tree successor with a nil node as a child */
while(y->left!=t->nil){
y=y->left;
}
}
/* x is y's only child */
if(y->left!=t->nil){
x=y->left;
}
else{
x=y->right;
}
/* delete y from parent chain */
x->parent=y->parent;
if(y->parent!=t->nil){
if(y==y->parent->left){
y->parent->left=x;
}
else{
y->parent->right=x;
}
}
else{
t->root=x;
}

if(y!=z){
z->key=y->key;
z->val=y->val;
}

if(RBT_IS_BLACK(y)){
rbt_delete_fixup(t,x);
}

return(y);
}

rb_node_t *rbt_find(rb_tree_t *t,int key)
{
rb_node_t *y=t->root;

while(y!=t->nil){
if(EQ(key,y->key)){
return(y);
}
else{
y=LT(key,y->key)?y->left:y->right;
}
}

return(NULL);
}

void rbt_in_order(rb_tree_t *t,void (*RbtOrderCallBack)(rb_node_t *))
{
if(t->root==t->nil){
return;
}
rbt_in_order_internal(t,t->root,RbtOrderCallBack);
}

rb_node_t *rbt_min(rb_tree_t *t)
{
rb_node_t *node=t->root;

while (node->left != t->nil) {
node = node->left;
}

return node;
}

rb_node_t *rbt_max(rb_tree_t *t)
{
rb_node_t *node=t->root;

while (node->right != t->nil) {
node = node->right;
}

return node;
}


测试代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

#include "redblacktree.h"

void PrintTree(rb_node_t *t)
{
printf("key:%03d\tval:%04d\tcolor:%d\n",t->key,*((int *)t->val),t->color);
}

int main()
{
rb_tree_t tree;
rb_node_t nil;
rb_node_t *node;
rb_node_t *dst;
int i=0,ch,val[2000];

rbt_init(&tree,&nil);
printf("sizeof(rb_redblack_node_t):%d\n",sizeof(rb_node_t));
node=(rb_node_t *)malloc(2000*sizeof(rb_node_t));
if(node){
for(i=10;i<1000;i++){
node[i].key=i;
val[i]=2*i;
node[i].val=&val[i];
ch=rbt_insert(&tree,&node[i]);
}
}
else{
printf("malloc failed\n");
}
i=900;
printf("rbt_find\n");
dst=rbt_find(&tree,i);
if(dst){
ch=*((int *)dst->val);
printf("rbt_find:%d\tval:%d\n",dst->key,ch);
}
else{
printf("rbt_find NULL\n");
}
printf("rbt_in_order\n");
rbt_in_order(&tree,PrintTree);
printf("rbt_delete\n");
if(dst){
rbt_delete(&tree,dst);
}
printf("rbt_in_order after delete\n");
rbt_in_order(&tree,PrintTree);

dst=rbt_min(&tree);
if(dst){
printf("rbt_min:%d\tval:%d\tcolor:%d\n",dst->key,*((int *)dst->val),dst->color);
}
dst=rbt_max(&tree);
if(dst){
printf("rbt_max:%d\tval:%d\tcolor:%d\n",dst->key,*((int *)dst->val),dst->color);
}

return(0);
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: