红黑树的插入与删除

sourceforge源码下载:

https://sourceforge.net/project/showfiles.php?group_id=202044

红黑树插入与删除代码实现

简述:stl map的底层实现,rbtree关于红黑树的插入,侯杰的stl源码剖析已经做了很详细的说明,在此不赘述。这里主要讲一下红黑树的删除,并给出源码实例,代码在vs7上调通并测试正确算法说明:
/*
*
*从rb树中删除一个节点*
*删除除节点 z , 则可以用y完全取代z(位置,颜色,用户数据), 删除z演变成删除y*
* 图1
*      a                         a
*     / /                       / /
*    ?   z                     ?   y
*       / /       ---->           / /
*      ?   b                     ?   b
*         / /                       / /
*        y   ?            del ---> z   ?
*         /                         /
*          ?1                        ?1
*
*
*如果z是红色 则?1对应的子树根节点直接挪到z对应的位置,即完成了删除工作,并保证了红黑树的平衡性
*如果z是黑色 并且?1对应的子树根节点x为红色,则把?1挪到z的位置,并把x改成黑色,即完成了删除工作,并保证了红黑树的平衡性
*如果z是黑色 并且?1对应的子树根节点x也为黑色。
*图2
*
*     ?
*    / /
*   ?   x_parent
*      / /
*     x   ?2 = w
*    / /
*   ?   ?
*图2即最终要面临的情况
*x这个分支,由于去除了一个黑色的结点,而x又是黑色,它比 ?2 那个分支相比,
"少了一个黑色的结点
"
*
*图3
*       x_parent              x_parent->parent
*       /   /                   /           /
*      x     w     -->        x_parent       w_new
*     / /   / /               / /
*    ?   ? ?b  ?b            ?   ?
*假如?b ?b均为"黑" w也为黑 则把 w涂成红  此时x分支与w分支"黑层数"相同 ,
*(x_parent有可能为红,但这不影响结果,因为在下一个循环中,x = x_parent,循环将退出,x即x_parent将被涂成黑,不违反红黑树规则)
*以x = x_parent比 w = w_new这个分支"少了一层" 持续向上迭代 (x = x_parent x_parent = x->parent) 至到根节点为至,即完成了删除工作,并保证了红黑树的平衡
*
*如果w为红,通过旋转,可以演化成图3的情况
*演化步骤如下:
*把w涂成黑色,x_parent涂成红色(根据红黑树定义x_parent必为黑色, w的左右子节点必为黑色)
*以x_parent为轴左旋
*                   w
*                  / /
*          x_parent    ?b
*          /    /
*         x     ?b = w_new(必为黑)
*        / /
*       ?   ?
*  x 分支比 ?b分支少了一层
*
* 即,不管w为红还是为黑,最终都可以演化成w为黑的情况
*
*w的子节点中有红色节点的情况
*这种情况可以考虑把w的红色节点转移到x分支,作为x分支的根节点,并涂成黑色,即完成了删除,并保证了红黑树的平衡
*具体变换如下 如果a不为红,可以经过旋转变换为红
*
*     x_parent?
*      /      /
*     x        w黑      
*    / /      / /
*   ?   ?    黑b 红a
*
*              w?
*             /  /
*      x_parent黑 黑a
*     /  /
*    x   黑b
*即完成了删除,并保证了红黑树的平衡性
*
*/.h文件,接口说明 mymempool.h是一个内存池的接口,只提供内存分配功能,不影响算法的表述。==========================================================
myrbtree.h
/*
*
* myrbtree.h 红黑树
*
* author:lin shao chuan (email:lsccsl@tom.com, msn:lsccsl@163.net)
*
*/
#ifndef __MYRBTREE_H__
#define __MYRBTREE_H__


#include "mymempool.h"


/*
*
*1 表示 key1 比 key2 大
*0 表示 key1 比 key2 小
*
*/
typedef int (*myrbtree_compare)(const void * key1, const void * key2);

typedef struct __handle_myrbtree
{
    int unused;
}handle_myrbtree;
typedef handle_myrbtree * HMYRBTREE;

typedef struct __handle_myrbtree_iter
{
    int unused;
}handle_myrbtree_iter;
typedef handle_myrbtree_iter * HMYRBTREE_ITER;

/*
*
*创建rb树
*
*/
extern HMYRBTREE MyRBTreeConstruct(HMYMEMPOOL hm, myrbtree_compare compare);

/*
*
*销毁rb树
*
*/
extern void MyRBTreeDestruct(HMYRBTREE htree);

/*
*
*删除所有节点
*
*/
extern void MyRBTreeClear(HMYRBTREE htree);

/*
*
*往rb树中插入一个节点
*
*/
extern HMYRBTREE_ITER MyRBTreeInsertEqual(HMYRBTREE htree, const void * key, const void * userdata);

/*
*
*往rb树中插入一个节点
*
*/
extern HMYRBTREE_ITER MyRBTreeInsertUnique(HMYRBTREE htree, const void * key, const void * userdata);

/*
*
*从rb树中删除一个节点
*
*/
extern void MyRBTreeDelIter(HMYRBTREE htree, HMYRBTREE_ITER iter, void ** key, void ** data);

/*
*
*根据键值删除一个节点
*成功删除返回0, 否则返回-1
*
*/
extern int MyRBTreeDelKey(HMYRBTREE htree, const void * key, void ** key_ret, void ** data_ret);

/*
*
*获取节点的用户数据
*
*/
extern void * MyRBTreeGetIterData(const HMYRBTREE_ITER iter);

/*
*
*获取节点的键
*
*/
extern const void * MyRBTreeGetIterKey(const HMYRBTREE_ITER iter);

/*
*
*查找节点
*
*/
extern HMYRBTREE_ITER MyRBTreeSearch(const HMYRBTREE htree, const void * key);

/*
*
*计算最大层数
*
*/
extern int MyRBTreeLayer(const HMYRBTREE htree, int bmax);

/*
*
*"获取第一个节点"
*
*/
extern HMYRBTREE_ITER MyRBTreeBegin(const HMYRBTREE htree);

/*
*
*"获取最后一个节点"
*
*/
extern HMYRBTREE_ITER MyRBTreeEnd(const HMYRBTREE htree);

/*
*
*获取"下"一个节点
*
*/
extern HMYRBTREE_ITER MyRBTreeGetNext(const HMYRBTREE_ITER it);

/*
*
*获取"上"一个节点
*
*/
extern HMYRBTREE_ITER MyRBTreeGetPrev(const HMYRBTREE_ITER it);

/*
*
*检查红黑树是否合法
*
*/
extern int MyRBTreeExamin(const HMYRBTREE htree);

/*
*
*获取个数
*
*/
extern int MyRBTreeGetRealCount(const HMYRBTREE htree);


#endif
=============================================================
myrbtree.c

#include <stdlib.h>
#include <memory.h>
#include <assert.h>

#include "myutility.h"
#include "myrbtree.h"


typedef enum __rbtree_colour
{
    rbtree_colour_black,
    rbtree_colour_red,
}rbtree_colour;

typedef struct __myrbtree_node_t
{
    struct __myrbtree_node_t * left;
    struct __myrbtree_node_t * right;
    struct __myrbtree_node_t * parent;

    rbtree_colour colour;

    void * key;
    void * data;
}myrbtree_node_t;

typedef struct __myrbtree_t
{
    myrbtree_node_t * root;

    //内存池
    HMYMEMPOOL hm;

    //比较运算符
    myrbtree_compare compare;
}myrbtree_t;

/*
*
*1 表示 key1 比 key2 大
*0 表示 key1 比 key2 小
*
*/
static __INLINE__ int rbtree_inter_compare(myrbtree_t * rbtree, const void * key1, const void * key2)
{
    assert(rbtree && rbtree->compare);

    return (*rbtree->compare)(key1, key2);
}

static __INLINE__ myrbtree_node_t * rbtree_inter_create_node(myrbtree_t * rbtree, const void * key, const void * data)
{
    myrbtree_node_t * node_new = NULL;

    assert(rbtree);

    node_new = (myrbtree_node_t *)MyMemPoolMalloc(rbtree->hm, sizeof(*node_new));

    if(NULL == node_new)
        return NULL;

    memset(node_new, 0, sizeof(*node_new));
    node_new->key = (void *)key;
    node_new->data = (void *)data;

    return node_new;
}

static __INLINE__ void rbtree_inter_destroy_node(myrbtree_t * rbtree, myrbtree_node_t * node)
{
    assert(rbtree && node);

    MyMemPoolFree(rbtree->hm, node);
}

/*
*
*左旋
*
*   A                node
*    /              /
*     /    ---->   /
*      node       A
*/
static __INLINE__ void rbtree_inter_rotate_left(/*myrbtree_t * rbtree*/myrbtree_node_t ** root, myrbtree_node_t * node)
{
    myrbtree_node_t * A_node = NULL;

    assert(root && node && node->parent);

    A_node = node->parent;

    node->parent = A_node->parent;
    if(A_node->parent)
    {
        if(A_node == A_node->parent->left)
            A_node->parent->left = node;
        else
            A_node->parent->right = node;
    }
    A_node->parent = node;

    A_node->right = node->left;
    if(node->left)
        node->left->parent = A_node;

    node->left = A_node;

    if(A_node == *root)
        *root = node;

    assert(NULL == *root || NULL == (*root)->parent);
}

/*
*
*右旋
*
*     A        node
*    /          /
*   /    --->    /
*  node           A
*/
static __INLINE__ void rbtree_inter_rotate_right(/*myrbtree_t * rbtree*/myrbtree_node_t ** root, myrbtree_node_t * node)
{
    myrbtree_node_t * A_node = NULL;

    assert(root && node && node->parent);

    A_node = node->parent;
    node->parent = A_node->parent;
    if(A_node->parent)
    {
        if(A_node == A_node->parent->left)
            A_node->parent->left = node;
        else
            A_node->parent->right = node;
    }
    A_node->parent = node;

    A_node->left = node->right;
    if(node->right)
        node->right->parent = A_node;

    node->right = A_node;

    if(A_node == *root)
        *root = node;

    assert(NULL == (*root) || NULL == (*root)->parent);
}

static __INLINE__ myrbtree_node_t * rbtree_inter_search(myrbtree_t * rbtree, myrbtree_node_t * root, const void * key)
{
    myrbtree_node_t * y = NULL;/* 记录最后一个不大于key的节点 */
    myrbtree_node_t * x = root;

    assert(rbtree);

    while(x)
    {
        if(!rbtree_inter_compare(rbtree, x->key, key))
            y = x, x = x->right;
        else
            x = x->left;
    }

    return (NULL == y || rbtree_inter_compare(rbtree, key, y->key))?NULL:y;
}

static __INLINE__ myrbtree_node_t * rbtree_inter_searchex(myrbtree_t * rbtree, myrbtree_node_t * root, const void * key, myrbtree_node_t ** parent)
{
    myrbtree_node_t * y = NULL;/* 记录最后一个不大于key的节点 */
    myrbtree_node_t * x = root;

    assert(rbtree && parent /*&& rbtree->root == root*/);

    *parent = root;

    while(x)
    {
        *parent = x;

        if(!rbtree_inter_compare(rbtree, x->key, key))
            y = x, x = x->right;
        else
            x = x->left;
    }

    return (NULL == y || rbtree_inter_compare(rbtree, key, y->key))?NULL:y;
}

static __INLINE__ int rbtree_inter_ismynode(const myrbtree_node_t * root, const myrbtree_node_t * node)
{
    int ret = 0;

    if(NULL == root)
        return 0;

    if(node == root)
        return 1;

    if(root->left)
        ret = rbtree_inter_ismynode(root->left, node);
    if(ret)
        return ret;

    if(root->right)
        return rbtree_inter_ismynode(root->right, node);

    return 0;
}

/*
*
*旋转红黑树,使之符合红黑树的规则
*rbtree:需要旋转的红黑树
*node:新加入的节点
*
*/
static __INLINE__ void rbtree_inter_rebalance(/*myrbtree_t * rbtree*/myrbtree_node_t ** root, myrbtree_node_t * node)
{
    assert(root && node && node->parent);

    //新加入节点必为红
    node->colour = rbtree_colour_red;

    //如果父节点为根节点,根据红黑树的定义根节点必为黑
    if(node->parent == *root)
        return;

    //不为根结点,祖父节点必存在
    assert(node->parent->parent);

    //如果父节点不为黑
    while(node != *root && rbtree_colour_red == node->parent->colour)
    {
        //如果父节点是祖父节点的左孩子
        if(node->parent == node->parent->parent->left)
        {
            //如果伯父节点存在,且为红
            if(node->parent->parent->right && rbtree_colour_red == node->parent->parent->right->colour)
            {
                //把父节点与伯父节点涂成黑色
                node->parent->colour = rbtree_colour_black;
                node->parent->parent->right->colour = rbtree_colour_black;

                //把祖父结点涂成红色
                node->parent->parent->colour = rbtree_colour_red;

                //指针往上走
                node = node->parent->parent;
            }
            else
            {
                //如果是外侧插入
                if(node == node->parent->left)
                {
                    //node为红
                    node->colour = rbtree_colour_red;

                    //父节点为黑
                    node->parent->colour = rbtree_colour_black;

                    //祖父节点为红
                    node->parent->parent->colour = rbtree_colour_red;

                    //父节点为轴右旋转
                    rbtree_inter_rotate_right(root, node->parent);
                }
                else
                {
                    myrbtree_node_t * temp = node->parent;

                    //node为黑
                    node->colour = rbtree_colour_black;

                    //父节点为红
                    node->parent->colour = rbtree_colour_red;

                    //祖父节点为红
                    node->parent->parent->colour = rbtree_colour_red;

                    //node为轴左旋转
                    rbtree_inter_rotate_left(root, node);

                    //父节点为轴右旋转右旋转
                    rbtree_inter_rotate_right(root, node);

                    node = temp;
                }
            }
        }
        //如果父节点是祖父节点的右孩子
        else
        {
            //如果伯父节点存在,且为红
            if(node->parent->parent->left && rbtree_colour_red == node->parent->parent->left->colour)
            {
                //把父节点与伯父节点涂成黑色
                node->parent->colour = rbtree_colour_black;
                node->parent->parent->left->colour = rbtree_colour_black;

                //把祖父结点涂成红色
                node->parent->parent->colour = rbtree_colour_red;

                //指针往上走
                node = node->parent->parent;
            }
            else
            {
                //如果是外侧插入
                if(node == node->parent->right)
                {
                    //node为红
                    node->colour = rbtree_colour_red;

                    //父节点为黑
                    node->parent->colour = rbtree_colour_black;

                    //祖父节点为红
                    node->parent->parent->colour = rbtree_colour_red;

                    //父节点为轴左旋
                    rbtree_inter_rotate_left(root, node->parent);
                }
                else
                {
                    myrbtree_node_t * temp = node->parent;

                    //node为黑
                    node->colour = rbtree_colour_black;

                    //父节点为红
                    node->parent->colour = rbtree_colour_red;

                    //祖父节点为红
                    node->parent->parent->colour = rbtree_colour_red;

                    //node为轴右旋转
                    rbtree_inter_rotate_right(root, node);

                    //父节点为轴左旋
                    rbtree_inter_rotate_left(root, node);

                    node = temp;
                }
            }
        }
    }

    (*root)->colour = rbtree_colour_black;
}

/*
*
*添加一节点
*rbtree:树
*parent:新节点的父节点
*key:新节点的关键字
*
*/
static __INLINE__ void rbtree_inter_insert(myrbtree_t * rbtree, myrbtree_node_t ** root, myrbtree_node_t * node_new, myrbtree_node_t * parent)
{
    assert(rbtree && node_new && root);

    //如果父节点为空,表明添加的是根节点
    if(NULL == parent)
    {
        //根节点必有黑色
        node_new->colour = rbtree_colour_black;
        *root = node_new;

        assert(NULL == *root || NULL == (*root)->parent);

        return;
    }

    node_new->parent = parent;

    //比较节点键值与父节点键值大小
    if(rbtree_inter_compare(rbtree, node_new->key,parent->key))
        parent->right = node_new;
    else
        parent->left = node_new;

    //旋转树,使之符合红黑树的规则
    rbtree_inter_rebalance(root, node_new);
}

/*
*
*从rb树中删除一个节点
*
*删除除节点 z , 则可以用y完全取代z(位置,颜色,用户数据), 删除z演变成删除y
*
* 图1
*      a                         a
*     / /                       / /
*    ?   z                     ?   y
*       / /       ---->           / /
*      ?   b                     ?   b
*         / /                       / /
*        y   ?            del ---> z   ?
*         /                         /
*          ?1                        ?1
*
*
*如果z是红色 则?1对应的子树根节点直接挪到z对应的位置,即完成了删除工作,并保证了红黑树的平衡性
*如果z是黑色 并且?1对应的子树根节点x为红色,则把?1挪到z的位置,并把x改成黑色,即完成了删除工作,并保证了红黑树的平衡性
*如果z是黑色 并且?1对应的子树根节点x也为黑色。
*图2
*
*     ?
*    / /
*   ?   x_parent
*      / /
*     x   ?2 = w
*    / /
*   ?   ?
*图2即最终要面临的情况
*x这个分支,由于去除了一个黑色的结点,而x又是黑色,它比 ?2 那个分支相比,"少了一个黑色的结点"
*
*图3
*       x_parent              x_parent->parent
*       /   /                   /           /
*      x     w     -->        x_parent       w_new
*     / /   / /               / /
*    ?   ? ?b  ?b            ?   ?
*假如?b ?b均为"黑" w也为黑 则把 w涂成红  此时x分支与w分支"黑层数"相同 ,
*(x_parent有可能为红,但这不影响结果,因为在下一个循环中,x = x_parent,循环将退出,x即x_parent将被涂成黑,不违反红黑树规则)
*以x = x_parent比 w = w_new这个分支"少了一层" 持续向上迭代 (x = x_parent x_parent = x->parent) 至到根节点为至,即完成了删除工作,并保证了红黑树的平衡
*
*如果w为红,通过旋转,可以演化成图3的情况
*演化步骤如下:
*把w涂成黑色,x_parent涂成红色(根据红黑树定义x_parent必为黑色, w的左右子节点必为黑色)
*以x_parent为轴左旋
*                   w
*                  / /
*          x_parent    ?b
*          /    /
*         x     ?b = w_new(必为黑)
*        / /
*       ?   ?
*  x 分支比 ?b分支少了一层
*
* 即,不管w为红还是为黑,最终都可以演化成w为黑的情况
*
*w的子节点中有红色节点的情况
*这种情况可以考虑把w的红色节点转移到x分支,作为x分支的根节点,并涂成黑色,即完成了删除,并保证了红黑树的平衡
*具体变换如下 如果a不为红,可以经过旋转变换为红
*
*     x_parent?
*      /      /
*     x        w黑     
*    / /      / /
*   ?   ?    黑b 红a
*
*              w?
*             /  /
*      x_parent黑 黑a
*     /  /
*    x   黑b
*即完成了删除,并保证了红黑树的平衡性
*
*/
static __INLINE__ myrbtree_node_t * rbtree_inter_rebalance_for_erase(/*myrbtree_t * rbtree*/myrbtree_node_t ** root, myrbtree_node_t * node)
{
    myrbtree_node_t * x = NULL;
    myrbtree_node_t * x_parent = NULL;
    myrbtree_node_t * y = node;

    assert(node && root);
   
    if(NULL == node->left)
        x = node->right;
    else if(NULL == node->right)
        x = node->left;
    else
    {
        //如果node不是叶子结点,则寻找右子树中最"左"边的那个节点替代node
        y = node->right;
        while(y->left)
            y = y->left;

        x = y->right;
    }

    //要删除的节点左右孩子都不为空,y与node 互换
    if(y != node)
    {
        //颜色互换
        rbtree_colour colour = y->colour;
        y->colour = node->colour;
        node->colour = colour;

        if(node->parent)
        {
            if(node == node->parent->left)
                node->parent->left = y;
            else
                node->parent->right = y;
        }
        else if(node == *root)
            *root = y;
        else
            assert(0);//如果走到这一步 bug here

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

        //如果y是node的右孩子
        if(y == node->right)
        {
            x_parent = y;
        }
        else
        {
            if(node->right)
                node->right->parent = y;

            assert(y->parent);
            x_parent = y->parent;

            if(y == x_parent->left)
                x_parent->left = x;
            else
                assert(0);//x_parent->right = x; //y不可能是x_parent的右孩子 如果走到这一步,bug

            y->right = node->right;
        }

        y->parent = node->parent;
        y->left = node->left;

        y = node;
    }
    else//y就是要删除的节点,不必做替换,且y必有一孩子节点为空
    {
        //如果要删除的是根节点
        if(y == *root)
        {
            *root = x;
            if(*root)
            {
                (*root)->colour = rbtree_colour_black;
                (*root)->parent = NULL;
            }

            assert(NULL == *root || NULL == (*root)->parent);

            return y;
        }
        else
        {
            assert(y->parent);

            x_parent = y->parent;
            if(y == x_parent->left)
                x_parent->left = x;
            else
                x_parent->right = x;
        }
    }

    assert(x_parent);   

    if(x)
        x->parent = x_parent;

    //转化成
    //*      a                         a
    //*     / /                       / /
    //*    ?   z                     ?   y
    //*       / /       ---->           / /
    //*      ?   b                     ?   b
    //*         / /                       / /
    //*        y   ?            del ---> z   ?
    //*         /                         /
    //*          ?1                        ?1

    //如果要删除的节点为红色,函数返回
    if(y->colour == rbtree_colour_red)
    {
        assert(NULL == *root || NULL == (*root)->parent);
        return y;
    }

    while((x != *root) && (x == NULL || rbtree_colour_black == x->colour))
    {
        assert(x_parent);

        if(x == x_parent->left)
        {
            myrbtree_node_t * w = x_parent->right;
            assert(w);//x分支为0/1个黑结点,w分支至少有一个黑结点,所以w分支不可能为null,

            //如果w是红,需要进行转换,
            if(rbtree_colour_red == w->colour)
            {
                //x_parent必定是黑色的,且w的两个子节点必不空,且一定为黑色
                assert(rbtree_colour_black == x_parent->colour);
                assert(w->left && rbtree_colour_black == w->left->colour);
                assert(w->right && rbtree_colour_black == w->right->colour);

                w->colour = rbtree_colour_black;
                x_parent->colour = rbtree_colour_red;

                //旋转
                rbtree_inter_rotate_left(root, w);

                w = x_parent->right;
            }

            //x分支比w分支"少了一层",且x,w均为黑
            assert(w);

            //如果w的左右子节点均为黑
            if( (NULL == w->left || rbtree_colour_black == w->left->colour) &&
                (NULL == w->right || rbtree_colour_black == w->right->colour) )
            {
                //x_parent有可能为红,但这不影响结果,因为在下一个循环中,x = x_parent,循环将退出,x即x_parent将被涂成黑,不违反红黑树规则
                w->colour = rbtree_colour_red;
                x = x_parent;
                x_parent = x->parent;
                continue;
            }

            //如果至少有一个子节点为红, 通过旋转变换,让为红的那个节点始终为右节点
            if(NULL == w->right || rbtree_colour_black == w->right->colour)
            {
                assert(w->left && rbtree_colour_red == w->left->colour);//根据逻辑得出,必为不空,且必为红色
               
                w->left->colour = rbtree_colour_black;
                w->colour = rbtree_colour_red;
                rbtree_inter_rotate_right(root, w->left);
                w = x_parent->right;
            }

            //现在演变成这种情况
            //*     x_parent?
            //*      /      /
            //*     x        w黑     
            //*    / /      / /
            //*   ?   ?    ?b 红a
            assert(w->right && rbtree_colour_red == w->right->colour);//根据逻辑,这个条件必成立

            //旋转,完成了平衡的工作,变换过程如下图
            //*     x_parent?
            //*      /      /
            //*     x        w黑     
            //*    / /      / /
            //*   ?   ?    黑b 红a
            //*
            //*              w?
            //*             /  /
            //*      x_parent黑 黑a
            //*     /  /
            //*    x   黑b
            w->colour = x_parent->colour;
            x_parent->colour = rbtree_colour_black;
            w->right->colour = rbtree_colour_black;
            rbtree_inter_rotate_left(root, w);
            break;
        }
        else//x 是 x_parent的右孩子,操作与x == x_parent->left相同,但左右相反
        {
            myrbtree_node_t * w = x_parent->left;
            assert(w);//x分支为0/1个黑结点,w分支至少有一个黑结点,所以w分支不可能为null,

            //如果w是红,需要进行转换,
            if(rbtree_colour_red == w->colour)
            {
                //x_parent必定是黑色的,且w的两个子节点必不空,且一定为黑色
                assert(rbtree_colour_black == x_parent->colour);
                assert(w->left && rbtree_colour_black == w->left->colour);
                assert(w->right && rbtree_colour_black == w->right->colour);

                w->colour = rbtree_colour_black;
                x_parent->colour = rbtree_colour_red;

                //旋转
                rbtree_inter_rotate_right(root, w);

                w = x_parent->left;
            }

            //x分支比w分支"少了一层",且x,w均为黑
            assert(w);

            //如果w的左右子节点均为黑
            if( (NULL == w->left || rbtree_colour_black == w->left->colour) &&
                (NULL == w->right || rbtree_colour_black == w->right->colour) )
            {
                //x_parent有可能为红,但这不影响结果,因为在下一个循环中,x = x_parent,循环将退出,x即x_parent将被涂成黑,不违反红黑树规则
                w->colour = rbtree_colour_red;
                x = x_parent;
                x_parent = x->parent;
                continue;
            }

            //如果至少有一个子节点为红, 通过旋转变换,让为红的那个节点始终为右节点
            if(NULL == w->left || rbtree_colour_black == w->left->colour)
            {
                assert(w->right && rbtree_colour_red == w->right->colour);//根据逻辑得出,必为不空,且必为红色
               
                w->right->colour = rbtree_colour_black;
                w->colour = rbtree_colour_red;
                rbtree_inter_rotate_left(root, w->right);
                w = x_parent->left;
            }

            assert(w->left && rbtree_colour_red == w->left->colour);//根据逻辑,这个条件必成立

            w->colour = x_parent->colour;
            x_parent->colour = rbtree_colour_black;
            w->left->colour = rbtree_colour_black;
            rbtree_inter_rotate_right(root, w);
            break;
        }
    }

    if(x)
        x->colour = rbtree_colour_black;

    //assert(!rbtree_inter_ismynode(rbtree->root, y));
    assert(NULL == (*root) || NULL == (*root)->parent);

    return y;
}

static __INLINE__ void rbtree_inter_del(myrbtree_t * rbtree, myrbtree_node_t ** root, myrbtree_node_t * node, void ** key, void ** data)
{
    assert(rbtree && node && root);

    //旋转平衡红黑树
    node = rbtree_inter_rebalance_for_erase(root, node);

    if(NULL == node)
        return;

    if(data)
        *data = node->data;

    if(key)
        *key = node->key;

    //销毁node
    rbtree_inter_destroy_node(rbtree, node);
}

static __INLINE__ int rbtree_inter_countlayer(myrbtree_node_t * root, int bmax)
{
    int left = 0;
    int right = 0;

    if(NULL == root)
        return 0;

    left = rbtree_inter_countlayer(root->left, bmax);
    right = rbtree_inter_countlayer(root->right, bmax);

    if(left > right && bmax)
        return left + 1;
    else
        return right + 1;
}

static __INLINE__ myrbtree_node_t * rbtree_inter_begin(myrbtree_t * rbtree)
{
    myrbtree_node_t * node;

    assert(rbtree);

    node = rbtree->root;
    if(NULL == node)
        return NULL;

    while(node->left)
        node = node->left;

    return node;
}

static __INLINE__ myrbtree_node_t * rbtree_inter_end(myrbtree_t * rbtree)
{
    myrbtree_node_t * node;

    assert(rbtree);

    node = rbtree->root;
    if(NULL == node)
        return NULL;

    while(node->right)
        node = node->right;

    return node;
}

static __INLINE__ void rbtree_inter_erase(myrbtree_t * rbtree, myrbtree_node_t * node)
{
    assert(node);

    while(node)
    {
        myrbtree_node_t * y = node->left;

        if(node->right)
            rbtree_inter_erase(rbtree, node->right);

        rbtree_inter_destroy_node(rbtree, node);

        node = y;
    }
}

static __INLINE__ int rbtree_inter_realcount(myrbtree_node_t * root)
{
    int left = 0;
    int right = 0;

    if(NULL == root)
        return 0;

    if(root->left)
        left = rbtree_inter_realcount(root->left);

    if(root->right)
        right = rbtree_inter_realcount(root->right);

    return left + right + 1;
}

static __INLINE__ int rbtree_inter_examin(myrbtree_t * rbtree, myrbtree_node_t * node)
{
    int left = 0;
    int right = 0;

    if(NULL == node)
        return 0;

    if(node->left)
    {
        assert(rbtree_inter_compare(rbtree, node->key, node->left->key));
        assert(node->left->parent == node);
        left = rbtree_inter_examin(rbtree, node->left);
    }

    if(node->right)
    {
        assert(rbtree_inter_compare(rbtree, node->right->key, node->key));
        assert(node->right->parent == node);
        right = rbtree_inter_examin(rbtree, node->right);
    }

    assert(left == right);

    if(rbtree_colour_black == node->colour)
        return left + 1;
    else
        return left;
}


/*
*
*创建rb树
*
*/
HMYRBTREE MyRBTreeConstruct(HMYMEMPOOL hm, myrbtree_compare compare)
{
    myrbtree_t * rbtree = NULL;

    rbtree = (myrbtree_t *)MyMemPoolMalloc(hm, sizeof(*rbtree));

    if(NULL == rbtree)
        return NULL;

    rbtree->compare = compare;
    rbtree->hm = hm;
    rbtree->root = NULL;

    return (HMYRBTREE)rbtree;
}

/*
*
*销毁rb树
*
*/
void MyRBTreeDestruct(HMYRBTREE htree)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;

    if(NULL == rbtree)
        return;

    //遍历树,释放每个节点
    if(rbtree->root)
        rbtree_inter_erase(rbtree, rbtree->root);

    MyMemPoolFree(rbtree->hm, rbtree);
}

/*
*
*删除所有节点
*
*/
void MyRBTreeClear(HMYRBTREE htree)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;

    if(NULL == rbtree)
        return;

    if(NULL == rbtree->root)
        return;

    //遍历树,释放每个节点
    rbtree_inter_erase(rbtree, rbtree->root);
    rbtree->root = NULL;
}

/*
*
*往rb树中插入一个节点
*
*/
HMYRBTREE_ITER MyRBTreeInsertEqual(HMYRBTREE htree, const void * key, const void * userdata)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;
    myrbtree_node_t * node_new = NULL;
    myrbtree_node_t * parent = NULL;

    if(NULL == rbtree)
        return NULL;

    rbtree_inter_searchex(rbtree, rbtree->root, key, &parent);

    node_new = rbtree_inter_create_node(rbtree, key, userdata);
    if(NULL == node_new)
        return NULL;

    rbtree_inter_insert(rbtree, &rbtree->root, node_new, parent);

    return (HMYRBTREE_ITER)node_new;
}

/*
*
*往rb树中插入一个节点
*
*/
HMYRBTREE_ITER MyRBTreeInsertUnique(HMYRBTREE htree, const void * key, const void * userdata)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;

    myrbtree_node_t * parent = NULL;
    myrbtree_node_t * node_new = NULL;

    if(NULL == rbtree)
        return NULL;
   
    node_new = rbtree_inter_searchex(rbtree, rbtree->root, key, &parent);
    if(node_new != NULL)
        return (HMYRBTREE_ITER)node_new;

    node_new = rbtree_inter_create_node(rbtree, key, userdata);
    if(NULL == node_new)
        return NULL;

    rbtree_inter_insert(rbtree, &rbtree->root, node_new, parent);

    return (HMYRBTREE_ITER)node_new;
}

/*
*
*从rb树中删除一个节点 iter失效
*
*/
void MyRBTreeDelIter(HMYRBTREE htree, HMYRBTREE_ITER iter, void ** key, void ** data)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;
    myrbtree_node_t * node = (myrbtree_node_t *)iter;

    if(NULL == rbtree || NULL == node)
        return;

    assert(rbtree_inter_search(rbtree, rbtree->root, node->key));

    rbtree_inter_del(rbtree, &(rbtree->root), node, key, data);
}

/*
*
*根据键值删除一个节点
*成功删除返回0, 否则返回-1
*
*/
int MyRBTreeDelKey(HMYRBTREE htree, const void * key, void ** key_ret, void ** data_ret)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;
    myrbtree_node_t * node = NULL;

    if(NULL == rbtree)
        return -1;

    node = rbtree_inter_search(rbtree, rbtree->root, key);

    if(NULL == node)
        return -1;

    rbtree_inter_del(rbtree, &(rbtree->root), node, key_ret, data_ret);

    return 0;
}

/*
*
*获取节点的用户数据
*
*/
void * MyRBTreeGetIterData(const HMYRBTREE_ITER iter)
{
    myrbtree_node_t * node = (myrbtree_node_t *)iter;

    if(NULL == node)
        return NULL;

    return node->data;
}

/*
*
*获取节点的键
*
*/
const void * MyRBTreeGetIterKey(const HMYRBTREE_ITER iter)
{
    myrbtree_node_t * node = (myrbtree_node_t *)iter;

    if(NULL == node)
        return NULL;

    return node->key;
}

/*
*
*查找节点
*
*/
HMYRBTREE_ITER MyRBTreeSearch(const HMYRBTREE htree, const void * key)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;
    myrbtree_node_t * node = NULL;

    if(NULL == rbtree || NULL == rbtree->compare)
        return NULL;

    node = rbtree_inter_search(rbtree, rbtree->root, key);

    return (HMYRBTREE_ITER)node;
}

/*
*
*计算最大层数
*
*/
int MyRBTreeLayer(const HMYRBTREE htree, int bmax)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;

    if(NULL == rbtree)
        return 0;

    return rbtree_inter_countlayer(rbtree->root, bmax);
}

/*
*
*"获取第一个节点"
*
*/
HMYRBTREE_ITER MyRBTreeBegin(const HMYRBTREE htree)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;

    if(NULL == rbtree)
        return 0;

    return (HMYRBTREE_ITER)rbtree_inter_begin(rbtree);
}

/*
*
*"获取最后一个节点"
*
*/
HMYRBTREE_ITER MyRBTreeEnd(const HMYRBTREE htree)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;

    if(NULL == rbtree)
        return 0;

    return (HMYRBTREE_ITER)rbtree_inter_end(rbtree);
}

/*
*
*获取下一个节点
*
*/
HMYRBTREE_ITER MyRBTreeGetNext(const HMYRBTREE_ITER it)
{
    myrbtree_node_t * node = (myrbtree_node_t *)it;

    if(NULL == node)
        return NULL;

    if(NULL == node->right)
    {
        while(node->parent && node == node->parent->right)
            node = node->parent;

        if(node->parent && node == node->parent->left)
            return (HMYRBTREE_ITER)node->parent;
        else
            return NULL;
    }
    else
    {
        node = node->right;
        while(node->left)
            node = node->left;

        return (HMYRBTREE_ITER)node;
    }
}

/*
*
*获取上一个节点
*
*/
HMYRBTREE_ITER MyRBTreeGetPrev(const HMYRBTREE_ITER it)
{
    myrbtree_node_t * node = (myrbtree_node_t *)it;

    if(node->left)
    {
        node = node->left;
        while(node->right)
            node = node->right;
        return (HMYRBTREE_ITER)node;
    }
    else
    {
        while(node->parent && node == node->parent->left)
            node = node->parent;

        if(node->parent && node == node->parent->right)
            return (HMYRBTREE_ITER)node->parent;
        else
            return NULL;
    }       
}

/*
*
*检查红黑树是否合法
*
*/
int MyRBTreeExamin(const HMYRBTREE htree)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;

    if(NULL == rbtree)
        return 0;

    return rbtree_inter_examin(rbtree, rbtree->root);
}

/*
*
*获取个数
*
*/
int MyRBTreeGetRealCount(const HMYRBTREE htree)
{
    myrbtree_t * rbtree = (myrbtree_t *)htree;

    if(NULL == rbtree)
        return 0;

    return rbtree_inter_realcount(rbtree->root);
}

#include "mymap.c"

#ifdef WIN32
    #include "MyStringSetEx.c"
#endif

==========================================================
mymempool.h
/*
*
* mymempool.h 内存池
*
* author:lin shao chuan (email:lsccsl@tom.com, msn:lsccsl@163.net)
*
*/
#ifndef __MYMEMPOOL_H__
#define __MYMEMPOOL_H__


#include "myconfig.h"
#include <stdlib.h>

/**
 * @brief 分配内存的回调函数
 */
typedef void *(*mymalloc)(size_t size, void * context_data);

/**
 * @brief 释放内存的回调函数
 */
typedef void(*myfree)(void *, void * context_data);

/**
 * @brief 观察内存池回调
 */
typedef void(*mempool_view)(void * context_data, void * info, size_t info_size);

/**
 * @brief 内存池销毁时的回调函数
 */
typedef void(*mempool_destroy)(void * context_data);

typedef struct __handle_mymempool
{int unused;} * HMYMEMPOOL;


/*
*
*构造内存池
*
*/
extern HMYMEMPOOL MyMemPoolConstruct(mymalloc malloc_helper, myfree free_helper, mempool_destroy destroy, mempool_view view, void * context_data);

/*
*
*销毁内存池
*
*/
extern void MyMemePoolDestruct(HMYMEMPOOL hm);

/*
*
*观察内存池
* @param info:返回的内存信息缓冲区
* @param info_size:info的大小
*
*/
extern void MyMemPoolView(HMYMEMPOOL hm, void * info, size_t info_size);

/*
*
*分配内存
*
*/
#ifdef MEM_LEAK_CHECK
    extern void * MemPoolMalloc(HMYMEMPOOL hm,size_t size, char * file, int line);
    #define MyMemPoolMalloc(h, s) MemPoolMalloc(h, s, __FILE__, __LINE__);
#else
    extern void * MyMemPoolMalloc(HMYMEMPOOL hm,size_t size);
#endif

/*
*
*释放内存
*
*/
extern void MyMemPoolFree(HMYMEMPOOL hm, void * ptr);

/*
*
*内存是否泄漏报告
*
*/
extern void MyMemPoolMemReport(int needassert);

/*
*
*获取分配了多少内存
*
*/
extern int MyMemPoolGetBlkCount();

#endif




======================================================
mymempool.c
/*
*
* mymempool.c 内存池
*
* author:lin shao chuan (email:lsccsl@tom.com, msn:lsccsl@163.net)
*
*/
#include "mymempool.h"


#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>


/**
 * 多线程安全(内存泄漏检测)
 */
#ifndef WIN32
    #include <pthread.h>
#else
    #include <windows.h>
    #define pthread_mutex_t CRITICAL_SECTION
    #define pthread_mutex_init(cs, x) do{ InitializeCriticalSection(cs); }while(0)
    #define pthread_mutex_lock(cs) do{ EnterCriticalSection(cs); }while(0)
    #define pthread_mutex_unlock(cs) do{ LeaveCriticalSection(cs); }while(0)
#endif

/**
 * 记录内存分配函数
 */
#ifdef MEM_LEAK_CHECK
    static void add_to_meminfo_list(const char * file, const int line, const void * ptr, size_t size);
    static void del_from_meminfo_list(const void * ptr);
    static int meminfo_report(int, int);
#endif


typedef struct __mymempool_t
{
    mymalloc malloc_fun;
    myfree free_fun;

    mempool_view view_fun;
   
    mempool_destroy destroy_fun;   
   
    /*
    * 用户自定义的上下文数据
    */
    void * context_data;
}mymempool_t;


/*
*
*构造内存池
*
*/
HMYMEMPOOL MyMemPoolConstruct(mymalloc malloc_helper, myfree free_helper, mempool_destroy destroy, mempool_view view, void * context_data)
{
    mymempool_t * mp = NULL;
    assert(malloc_helper && free_helper);

    mp = (mymempool_t *)malloc(sizeof(*mp));
    assert(mp);

    mp->destroy_fun = destroy;
    mp->context_data = context_data;
    mp->malloc_fun = malloc_helper;
    mp->free_fun = free_helper;
    mp->view_fun = view;

    return (HMYMEMPOOL)mp;
}

/*
*
*销毁内存池
*
*/
void MyMemePoolDestruct(HMYMEMPOOL hm)
{
    mymempool_t * mp = (mymempool_t *)hm;
    assert(mp);

    if(mp->destroy_fun)
        mp->destroy_fun(mp->context_data);

    free(mp);
}

/*
*
*观察内存池
*
*/
void MyMemPoolView(HMYMEMPOOL hm, void * info, size_t info_size)
{
    mymempool_t * mp = (mymempool_t *)hm;
    assert(mp);
   
    if(mp->view_fun)
        mp->view_fun(mp->context_data, info, info_size);
}

/*
*
*分配内存
*
*/
#ifdef MEM_LEAK_CHECK
    void * MemPoolMalloc(HMYMEMPOOL hm,size_t size, char * file, int line)
#else
    void * MyMemPoolMalloc(HMYMEMPOOL hm,size_t size)
#endif
{
    mymempool_t * mp = (mymempool_t *)hm;
    void * ptr = NULL;

    if(mp)
        ptr = mp->malloc_fun(size, mp->context_data);
    else
        ptr = malloc(size);

#ifdef MEM_LEAK_CHECK
    //添加到内存分配表
    add_to_meminfo_list(file, line, ptr, size);
#endif

    return ptr;
}

/*
*
*释放内存
*
*/
void MyMemPoolFree(HMYMEMPOOL hm, void * ptr)
{
    mymempool_t * mp = (mymempool_t *)hm;

#ifdef MEM_LEAK_CHECK
    //从内存分配表中删除
    del_from_meminfo_list(ptr);
#endif

    if(mp)
        mp->free_fun(ptr, mp->context_data);
    else
        free(ptr);
}


#ifdef MEM_LEAK_CHECK

/*
*
*获取做了几次内存分配操作
*
*/
int MyMemPoolGetBlkCount()
{
    return meminfo_report(0, 0);
}

/*
*
*内存分配报告
*
*/
void MyMemPoolMemReport(int needassert)
{
    meminfo_report(needassert, 1);
}

/**
 * 返回全局的锁对象指针
 */
static void * get_meminfo_lock()
{
    static int b_init = 0;
    static pthread_mutex_t mem_lock;

    if(!b_init)
    {
        pthread_mutex_init(&mem_lock, NULL);
        b_init = 1;
    }

    return &mem_lock;
}

/**
 * 内存记录表加锁
 */
static void meminfo_lock()
{
    pthread_mutex_lock((pthread_mutex_t *)get_meminfo_lock());
}

/**
 * 内存记录表解锁
 */
static void meminfo_unlock()
{
    pthread_mutex_unlock((pthread_mutex_t *)get_meminfo_lock());
}

/**
 * 内存分配记录表条目信息
 */
static struct __mymeminfo
{
    char file[64];
    int line;
    size_t size;
    void * ptr;

    struct __mymeminfo * next;
    struct __mymeminfo * prev;
} * head_meminfo_list = NULL;

/**
 * 往内存分配记录表里添加一条记录
 */
static void add_to_meminfo_list(const char * file, const int line, const void * ptr, size_t size)
{
    struct __mymeminfo * info = (struct __mymeminfo *)malloc(sizeof(*info));
    memset(info, 0, sizeof(*info));
   
    //加锁
    meminfo_lock();

    strncpy(info->file, file, sizeof(info->file));
    info->line = line;
    info->ptr = (void *)ptr;
    info->size = size;

    info->next = head_meminfo_list;
    if(head_meminfo_list)
        head_meminfo_list->prev = info;

    head_meminfo_list = info;

    //解锁
    meminfo_unlock();
}

/**
 * 往内存分配记录表里删除一条记录
 */
static void del_from_meminfo_list(const void * ptr)
{
    struct __mymeminfo * info = NULL;
   
    //加锁
    meminfo_lock();

    info = head_meminfo_list;

    while(info)
    {
        if(ptr != info->ptr)
        {
            info = info->next;
            continue;
        }

        if(info->prev)
            info->prev->next = info->next;

        if(info->next)
            info->next->prev = info->prev;

        if(info == head_meminfo_list)
            head_meminfo_list = info->next;

        free(info);

        break;
    }

    //解锁
    meminfo_unlock();
}

/**
 * 内存分配报告,用于检测是否出现了内存泄漏
 */
static int meminfo_report(int needassert, int bprintf)
{
    struct __mymeminfo * info = NULL;
    int leak_count = 0;

    printf("/n======== mem leak report begin ========/n");

    //加锁
    meminfo_lock();
   
    info = head_meminfo_list;

    while(info)
    {
        if(bprintf)
        {
            #ifdef _MBCSV6
            printf("[%s:%d] %3d - %x /n", info->file, info->line, info->size, info->ptr);
            #else
            #ifdef WIN32
            printf("[%s:%d] %3d - %x /n", info->file, info->line, info->size, (long long)info->ptr);
            #else
            printf("[%s:%d] %3d - %x /n", info->file, info->line, info->size, info->ptr);
            #endif
            #endif
        }

        info = info->next;

        leak_count ++;
    }

    //解锁
    meminfo_unlock();

    printf("mem leak %d/n", leak_count);

    printf("======== mem leak report end ==========/n/n");

    if(needassert)
        assert(0 == leak_count);

    return leak_count;
}
#else

void MyMemPoolMemReport(int needassert){}
int MyMemPoolGetBlkCount(){return 0;}


#endif






呵呵,相信如果不是对红黑树很感兴趣的人,是不会看到这里的,
笔者简介:林绍川
目前主要从事嵌入式开发,对算法有浓厚的兴趣欢迎交流 lsccsl@tom.com
写这个算法的主要原因是,在嵌入式开发过程中,有时使用stl是件麻烦的事。图省心,写了一些常用的容器,如hash rbtree list等,需要相应的源码请email给我。have fun :)
或者从 http://sourceforge.net/projects/foolib/files/ 下载
posted @ 2007-05-15 09:35  飞天大蟾蜍  阅读(24)  评论(0编辑  收藏  举报