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:
[email protected], msn:
[email protected])
*
*/
#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:
[email protected], msn:
[email protected])
*
*/
#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:
[email protected], msn:
[email protected])
*
*/
#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
呵呵,相信如果不是对红黑树很感兴趣的人,是不会看到这里的,
笔者简介:林绍川
写这个算法的主要原因是,在嵌入式开发过程中,有时使用stl是件麻烦的事。图省心,写了一些常用的容器,如hash rbtree list等,需要相应的源码请email给我。have fun :)
或者从 http://sourceforge.net/projects/foolib/files/ 下载