/*******************************************
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);
}

posted on 2010-04-14 15:40  七维  阅读(407)  评论(0编辑  收藏  举报