`
touchinsert
  • 浏览: 1329736 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

红黑树的插入与删除

 
阅读更多

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/ 下载
分享到:
评论

相关推荐

    红黑树插入与删除

    主要讲述红黑树的插入、查找、删除、并设计了测试程序去测试程序的正确性

    红黑树插入与删除.xmind

    红黑树的插入与删除各种情况,内容更正了之前版本的错误

    红黑树插入删除算法

    红黑树插入删除算法,算法导论上算法,可以运行

    红黑树的插入与删除_详细整理资料

    ### 红黑树的插入与删除:详细解析 红黑树是一种自平衡二叉查找树,由Rudolf Bayer在1972年发明,最初被称为“对称二叉B树”。它在1978年Leo J. Guibas和Robert Sedgewick的论文中获得了现代名称“红黑树”。红黑树...

    红黑树插入以及删除代码

    红黑树插入删除代码,一些关键地方有打注释,比较好理解 删除部分可以配合http://sunblog.72pines.com/rb-tree-erase/看

    红黑树的插入与删除、比较完善的

    1. **常规二叉搜索树插入**:首先,红黑树像普通二叉搜索树一样插入新节点,新插入的节点默认为红色。 2. **颜色调整**:由于插入红色节点可能导致违反红黑树的性质,因此需要进行颜色调整。调整通常通过“右旋”、...

    红黑树插入删除的平衡操作

    红黑树插入,删除时各种状态的平衡操作。

    红黑树插入删除伪算法

    在"红黑树插入删除伪算法(含图示)"文件中,你将能看到具体的操作流程和变化过程,这对于理解红黑树的内部工作机制非常有帮助。 总的来说,红黑树是一种高效的数据结构,广泛应用于数据库系统、编译器、虚拟机等...

    红黑树插入算法

    红黑树插入算法 红黑树是一种自平衡二叉查找树,它能够在O(log n)时间内完成插入、删除和查找操作。红黑树的插入算法是指在红黑树中插入新的节点,使得红黑树保持其平衡和性质。 红黑树插入算法的步骤可以分为以下...

    红黑树数据结构的实现及其插入删除

    红黑树的插入操作分为两步:首先进行普通的二叉查找树插入,然后通过`RB-INSERT-FIXUP`来恢复红黑树的性质。`RB-INSERT-FIXUP`中,`while`循环最多执行O(logn)次,因为每次循环都会将问题规模减半,而旋转操作不会...

    红黑树的插入详细图解,直接拿下红黑树

    红黑树是一种自平衡二叉查找树,它的主要特点是在保持二叉查找树特性的同时,通过特定的颜色规则来确保树的平衡,以达到快速查找、插入和删除的目的。红黑树的每个节点都有一个颜色属性,可以是红色或黑色。在插入新...

    红黑树-动态演示生成红黑树

    红黑树的插入、删除和查找操作都需要维护这些性质。当插入新节点时,初始设置为红色以避免破坏性质5,然后通过旋转和重新着色等操作来恢复红黑树的平衡。删除操作更加复杂,可能需要对树进行多次调整以保持红黑性质...

    红黑树插入算法C++实现

    - 设计一个`insert`函数来处理插入操作,首先执行正常的二叉搜索树插入,然后进行红黑树的调整。 - 调整过程中,可能需要递归调用`insertFixup`函数来修正树的结构,直到插入的新节点成为黑色节点或者到达根节点。...

    红黑树的设计和实现(插入,删除)

    红黑树的主要特点在于它引入了颜色属性(红色或黑色)来维护树的平衡,从而保证了在插入、删除等操作后的查找效率。 1. **颜色属性**: - 红黑树的每个节点都带有颜色属性,可以是红色或黑色。 - 根节点必须是...

    红黑树的源码与测试函数

    1. **myrbtree.c**:这是红黑树的主要实现文件,包含了红黑树节点的定义、插入、删除和查找等操作的代码。其中,节点通常包含键值、颜色、左子节点、右子节点以及父节点等字段。插入和删除操作需要保证红黑树的性质...

    红黑树的插入与删除(改)

    红黑树的插入与删除,验证并更正了文档的一些错位。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    红黑树理论及说解如何插入删除并图示说明

    插入操作首先像在普通二叉查找树中一样进行,然后根据新插入节点的情况调整树的结构以保持红黑树的性质。如果插入的节点是红色,那么它不会违反红黑树的性质。但如果插入的节点是黑色,可能需要进行颜色翻转或旋转...

    红黑树原理详解

    这里仅列举了一部分红黑树插入和删除的基本概念和处理策略。实际应用中,这些操作可能需要结合具体情况和红黑树的性质进行更复杂的调整。理解红黑树的工作原理对于实现高效的数据结构和算法至关重要,特别是在需要...

    红黑树 一张导图解决红黑树全部插入和删除问题 包含详细操作原理 情况对比.emmx

    本文的思维导图解决了红黑树全部插入和删除问题,包含详细操作原理,各种情况的对比和原因,资源的具体内容可查看我的相对应博文

Global site tag (gtag.js) - Google Analytics