C 工具库8:map

本篇介绍另外一个在C++ stl中常用的容器map.


我打算将map的实现容器和map接口分开,创建map的时候可以传递一个实现了interface_map_container接口的对象指针进来,如果这个参数
传0,则默认使用红黑树做实际的容器.


这样做的好处是用户可以根据性能需求传递自己定制的容器类.例如在游戏程序中常见的数据表.一般通过一个索引查询,并且在程序启动时候
将数据全部加载好,在以后的运行中,只会对数据进行查询,不会做任何修改的动作.在这种情况下,使用一个数组存放key,val对,再加载完成后
对数组排序,后面查询的时候使用2分法,显然比用红黑树或其它的二叉平衡树效率更高.


好了,下面介绍map的实现,首先定义了迭代器:

typedef struct map_iter
{
void *node;
struct map_iter (*next)(struct map_iter*);
void (*get_first)(struct map_iter,void*);
void (*get_second)(struct map_iter,void*);
void (*set_second)(struct map_iter,void*);
}map_iter;

迭代器定义了4个函数指针,分别用来获得后继迭代器,get key的值,以及get/set value.这四个函数是由各container类型负责的,例如红黑
数的next是由函数RB_iter_next实现的,它获取当前节点的后续节点.如果container是上面所说的数组实现的则next仅需增加下标,并返回
所指向的元素便可.


然后是container的接口:

struct interface_map_container
{
map_iter (*insert)(struct interface_map_container*,void*,void*);
map_iter (*erase)(struct interface_map_container*,map_iter);
void (*remove)(struct interface_map_container* rb,void*);
map_iter (*find)(struct interface_map_container* rb,void *);
map_iter (*begin)(struct interface_map_container* rb);
map_iter (*end)(struct interface_map_container* rb);
int (*size)(struct interface_map_container*);
int (*empty)(struct interface_map_container*);
void (*destroy)(struct interface_map_container**);
};

所有希望作为map底层存储容器的类型都必须实现interface_map_container接口定义的函数.


最后是map的默认容器红黑树,红黑树是一种复杂的数据结构,其具体定义及特性在这里就不介绍了,想要了解可以参考<算法导论>或<算法:C语言实现>.

不过这里还是推荐看wiki里的这个介绍,http://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91思想跟算法导论中是一样的,但是更简单

易懂(至少我是这么认为的,算法导论中对删除部分的处理看了半天还是似懂非懂,看过wiki的文章后立马就全都明白了)



下面介绍下红黑树实现方式的选择,<算法:C语言实现>中使用的是左倾斜红节点,这种实现方式相当直观,其插入和删除操作也很好理解.但是这在实现find和
erase的时候就性能差一点了.


我希望和C++ stl中的操作类似,find返回一个迭代器,将这个跌代器传入erase可以删除这个节点.在<算法:C语言实现>删除的过程是自顶向下,沿搜索路径,
将遇到的所有2 node转变成3或4 node这样使得在删除时容易处理.显然,在find中,这个过程是不需要的,只有在erase过程中才需要.这使得至少需要沿搜索路
径查找两次(一次在find的时候,一次在erase的时候).而<算法导论>中的实现就没有这个问题,可以直接传入迭代器,无须而外的搜索就可以删除目标节点.


最后贴上代码. 

rbtree.h

#ifndef _RBTREE_H
#define _RBTREE_H
#include "map.h"

typedef struct RBtree *RBtree_t;
extern RBtree_t RBtree_create(unsigned short,unsigned short,comp _comp);


struct interface_map_container;
extern void RBtree_destroy(struct interface_map_container**);

///检查是否有违反红黑树性质
extern void RBtree_check_vaild(RBtree_t);
#endif

rbtree.c

#include "RBtree.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "map.h"

typedef struct RBnode
{
struct RBnode *parent;
struct RBnode *left;
struct RBnode *right;
RBtree_t tree;
unsigned short color;
unsigned short key_size;
unsigned short val_size;
char data[1];//key & value
}RBnode;

#ifndef IMPLEMEMT
#define IMPLEMEMT(SUPER_CLASS) struct SUPER_CLASS super_class
#endif

struct RBtree
{
IMPLEMEMT(interface_map_container);
RBnode *root;
RBnode *nil;
unsigned int size;
unsigned short key_size;
unsigned short val_size;
comp compare_function;
RBnode dummy;//nil节点
};

#define RED 1
#define BLACK 2

//节点数据操作
inline static void *get_key(RBnode *n)
{
assert(n);
return (void*)(n->data);
}

inline static void *get_value(RBnode *n)
{
assert(n);
return (void*)(&(n->data[n->key_size]));
}

inline static void copy_key(RBnode *n,void *key)
{
memcpy(get_key(n),key,n->key_size);
}

inline static void copy_value(RBnode *n,void *value)
{
memcpy(get_value(n),value,n->val_size);
}

inline static int less(RBtree_t rb,void *left,void *right)
{
return rb->compare_function(left,right) == -1;
}

inline static int equal(RBtree_t rb,void *left,void *right)
{
return rb->compare_function(left,right) == 0;
}

inline static int more(RBtree_t rb,void *left,void *right)
{
return rb->compare_function(left,right) == 1;
}

extern map_iter RBtree_insert(struct interface_map_container *,void*,void*);
extern map_iter RBtree_erase(struct interface_map_container *,map_iter);
extern void RBtree_delete(struct interface_map_container *,void*);
extern map_iter RBtree_find(struct interface_map_container *,void *);
extern map_iter RBtree_begin(struct interface_map_container *);
extern map_iter RBtree_end(struct interface_map_container *);
extern int RBtree_size(struct interface_map_container *);
extern int RBtree_empty(struct interface_map_container *);

RBtree_t RBtree_create(unsigned short key_size,unsigned short val_size,comp _comp)
{
struct RBtree *rb = malloc(sizeof(*rb));
if(rb)
{
rb->size = 0;
rb->dummy.color = BLACK;
rb->nil = &rb->dummy;
rb->nil->tree = rb;
rb->root = rb->nil;
rb->key_size = key_size;
rb->val_size = val_size;
rb->compare_function = _comp;
rb->super_class.insert = RBtree_insert;
rb->super_class.erase = RBtree_erase;
rb->super_class.remove = RBtree_delete;
rb->super_class.find = RBtree_find;
rb->super_class.begin = RBtree_begin;
rb->super_class.end = RBtree_end;
rb->super_class.size = RBtree_size;
rb->super_class.empty = RBtree_empty;
rb->super_class.destroy = RBtree_destroy;
}
return rb;
}

void RBtree_destroy(struct interface_map_container **_rb)
{

}

/*
* 左右旋转
*/
static RBnode *rotate_left(RBtree_t rb,RBnode *n)
{
RBnode *parent = n->parent;
RBnode *right = n->right;
if(right == rb->nil)
return;

n->right = right->left;
right->left->parent = n;

if(n == rb->root)
rb->root = right;
else
{
if(n == parent->left)
parent->left = right;
else
parent->right = right;
}
right->parent = parent;
n->parent = right;
right->left = n;
}


static RBnode *rotate_right(RBtree_t rb,RBnode *n)
{
RBnode *parent = n->parent;
RBnode *left = n->left;
if(left == rb->nil)
return;
n->left = left->right;
left->right->parent = n;

if(n == rb->root)
rb->root = left;
else
{
if(n == parent->left)
parent->left = left;
else
parent->right = left;
}
left->parent = parent;
n->parent = left;
left->right = n;
}

inline static void color_flip(RBnode *n)
{
if(n->left && n->right)
{
n->color = RED;
n->left->color = n->right->color = BLACK;
}
}

static void insert_fix_up(RBtree_t rb,RBnode *n)
{
while(n->parent->color == RED)
{
RBnode *parent = n->parent;
RBnode *grand_parent = parent->parent;
if(parent == grand_parent->left)
{
RBnode *ancle = grand_parent->right;
if(ancle->color == RED)
{
//叔叔节点是红色,执行一次颜色翻转
color_flip(grand_parent);
n = grand_parent;
}
else
{
if(n == parent->right)
{
n = parent;
rotate_left(rb,n);
}

n->parent->color = BLACK;
n->parent->parent->color = RED;
rotate_right(rb,n->parent->parent);
}
}
else
{
RBnode *ancle = grand_parent->left;
if(ancle->color == RED)
{
//叔叔节点是红色,执行一次颜色翻转
color_flip(grand_parent);
n = grand_parent;
}
else
{
if(n == parent->left)
{
n = parent;
rotate_right(rb,n);
}
n->parent->color = BLACK;
n->parent->parent->color = RED;
rotate_left(rb,n->parent->parent);
}
}
}
rb->root->color = BLACK;
}

static RBnode *find(RBtree_t rb,void *key)
{
if(rb->root == rb->nil)
return rb->nil;
RBnode *cur = rb->root;
RBnode *pre;
while(cur != rb->nil)
{
pre = cur;
if(equal(rb,key,get_key(cur)))
return cur;
if(less(rb,key,get_key(cur)))
cur = cur->left;
else
cur = cur->right;
}
return pre;
}

RBnode *create_node(RBtree_t rb,void *key,void *value)
{

RBnode *n = malloc(sizeof(*n) + rb->key_size + rb->val_size - 1);
n->key_size = rb->key_size;
n->val_size = rb->val_size;
copy_key(n,key);
copy_value(n,value);
return n;
}

inline static RBnode *minimum(RBtree_t rb,RBnode *n)
{
while(n->left != rb->nil)
n = n->left;
return n;
}

inline static RBnode *maxmum(RBtree_t rb,RBnode *n)
{
while(n->right != rb->nil)
n = n->right;
return n;
}

//获得n的后继节点,为根节点的情况下返回nil
static RBnode *successor(RBtree_t rb,RBnode *n)
{
assert(rb);
if(n->right != rb->nil)
return minimum(rb,n->right);
RBnode *y = n->parent;
while(y != rb->nil && n == y->right)
{
n = y;
y = y->parent;
}
return y;
}

//获得n的前驱节点,为根节点的情况下返回nil
static RBnode *predecessor(RBtree_t rb,RBnode *n)
{
assert(rb);
if(n->left != rb->nil)
return maxmum(rb,n->left);
RBnode *y = n->parent;
while(y != rb->nil && n == y->left)
{
n = y;
y = y->parent;
}
return y;

}

static RBnode *get_delete_node(RBtree_t rb,RBnode *n)
{
if(n->left == rb->nil && n->right == rb->nil)
return n;
else if(n->right != rb->nil)
return minimum(rb,n->right);
else
return maxmum(rb,n->left);
}

static void delete_fix_up(RBtree_t rb,RBnode *n)
{
while(n != rb->root && n->color != RED)
{
RBnode *p = n->parent;
if(n == p->left)
{
RBnode *w = p->right;
if(w->color == RED)//兄弟为红
{
w->color = BLACK;
p->color = RED;
rotate_left(rb,p);
w = p->right;
}
//兄弟为黑
if(w->left->color == BLACK && w->right->color == BLACK)
{
//兄弟的两儿子为黑
w->color = RED;
n = p;
}
else
{
if(w->right->color == BLACK)
{
//兄弟的右孩子为黑
w->left->color == BLACK;
w->color = RED;
rotate_right(rb,w);
w = p->right;
}
//兄弟的右孩子为红
w->color = p->color;
p->color = BLACK;
w->right->color = BLACK;
rotate_left(rb,p);
n = rb->root;
}
}
else
{
RBnode *w = p->left;
if(w->color == RED)
{
w->color = BLACK;
p->color = RED;
rotate_right(rb,p);
w = p->left;
}
if(w->left->color == BLACK && w->right->color == BLACK)
{
w->color = RED;
n = p;
}
else
{
if(w->left->color == BLACK)
{
w->right->color == BLACK;
w->color = RED;
rotate_left(rb,w);
w = p->left;
}
w->color = p->color;
p->color = BLACK;
w->left->color = BLACK;
rotate_right(rb,p);
n = rb->root;
}
}
}
n->color = BLACK;
}

void rb_iter_get_first(map_iter iter,void *first)
{
RBnode *n = (RBnode*)iter.node;
memcpy(first,get_key(n),n->key_size);
}

void rb_iter_get_second(map_iter iter,void *second)
{
RBnode *n = (RBnode*)iter.node;
memcpy(second,get_value(n),n->val_size);
}

void rb_iter_set_second(map_iter iter,void *val)
{
RBnode *n = (RBnode*)iter.node;
copy_value(n,val);
}

static map_iter RB_iter_next(struct map_iter *iter)
{
RBnode *n = (RBnode*)iter->node;

RBtree_t rb = n->tree;

if(iter->node == rb->nil)
return (*iter);
RBnode *succ = successor(rb,n);
map_iter next ={0,RB_iter_next,rb_iter_get_first,rb_iter_get_second,rb_iter_set_second};
if(!succ)
next.node = rb->nil;
else
next.node = succ;
return next;
}


map_iter RBtree_begin(struct interface_map_container *_rb)
{
RBtree_t rb = (RBtree_t)_rb;
RBnode *min = minimum(rb,rb->root);
map_iter begin = {0,RB_iter_next,rb_iter_get_first,rb_iter_get_second,rb_iter_set_second};
begin.node = (min == 0 ? rb->nil : min);
return begin;
}

map_iter RBtree_end(struct interface_map_container *_rb)
{
RBtree_t rb = (RBtree_t)_rb;
map_iter end ={rb->nil,RB_iter_next,rb_iter_get_first,rb_iter_get_second,rb_iter_set_second};
return end;
}

map_iter RBtree_find(struct interface_map_container *_rb,void *key)
{
RBtree_t rb = (RBtree_t)_rb;
RBnode *n = find(rb,key);
if(n == rb->nil || equal(rb,key,get_key(n)) == 0)
return RBtree_end(_rb);

map_iter it ={n,RB_iter_next,rb_iter_get_first,rb_iter_get_second,rb_iter_set_second};
return it;
}

map_iter RBtree_insert(struct interface_map_container *_rb,void *key,void *val)
{
RBtree_t rb = (RBtree_t)_rb;
assert(rb);
RBnode *x = find(rb,key);
if(x != rb->nil && equal(rb,key,get_key(x)))
return RBtree_end(_rb);//不允许插入重复节点
RBnode *n = create_node(rb,key,val);
n->color = RED;
n->left = n->right = rb->nil;
n->tree = rb;

if(x == rb->nil)
{
n->parent = rb->nil;
rb->root = n;
}
else
{
n->parent = x;
if(less(rb,key,get_key(x)))
x->left = n;
else
x->right = n;
}
++rb->size;
insert_fix_up(rb,n);
map_iter it ={n,RB_iter_next,rb_iter_get_first,rb_iter_get_second,rb_iter_set_second};
return it;
}

static void rb_delete(RBtree_t rb,void *key,RBnode **succ)
{
assert(rb);
RBnode *n = find(rb,key);
if(equal(rb,key,get_key(n)))
{
RBnode *x = get_delete_node(rb,n);//获得实际被删除的节点

if(succ)
{
if(x == n || less(rb,get_key(x),get_key(n)))
*succ = successor(rb,x);
else
{
//被删除节点是自己的后继,后继的数据回被拷贝到当前节点
//所以删除以后,当前节点就是后继节点.
*succ = n;
}
}
RBnode *parent = x->parent;
RBnode **link = (x == parent->left)? &(parent->left):&(parent->right);
RBnode *z = rb->nil;
if(x->left != rb->nil || x->right != rb->nil)
{
if(x->left != rb->nil)
*link = x->left;
else
*link = x->right;
z = *link;
}
else
*link = rb->nil;

z->parent = parent;
if(n != x)
{
//拷贝数据
copy_key(n,get_key(x));
copy_value(n,get_value(x));
}
if(x != rb->root && x->color == BLACK)
delete_fix_up(rb,z);
if(x == rb->root)
rb->root = rb->nil;
free(x);
--rb->size;
}
}

void RBtree_delete(struct interface_map_container *_rb,void *key)
{
RBtree_t rb = (RBtree_t)_rb;
rb_delete(rb,key,0);
}

/*
* 删除当前节点返回后继节点的迭代器
*/
map_iter RBtree_erase(struct interface_map_container *_rb,map_iter it)
{
RBtree_t rb = (RBtree_t)_rb;
RBnode *succ = 0;
rb_delete(rb,get_key(it.node),&succ);
if(succ == 0)
return RBtree_end(_rb);
map_iter next ={succ,RB_iter_next,rb_iter_get_first,rb_iter_get_second,rb_iter_set_second};
return next;
}

RBtree_size(struct interface_map_container *_rb)
{
RBtree_t rb = (RBtree_t)_rb;
return rb->size;
}

RBtree_empty(struct interface_map_container *_rb)
{
RBtree_t rb = (RBtree_t)_rb;
return rb->size == 0;
}


static int check(RBtree_t rb,RBnode *n,int level,int black_level,int *max_black_level,int *max_level)
{
if(n == rb->nil)
return 1;
if(n->color == BLACK)
++black_level;
else
{
if(n->parent->color == RED)
{
printf("父节点颜色为RED\n");
return 0;
}
}
++level;
if(n->left == rb->nil && n->right == rb->nil)
{
//到达叶节点
if(level > *max_level)
*max_level = level;
if(*max_black_level == 0)
*max_black_level = black_level;
else
if(*max_black_level != black_level)
{
printf("黑色节点数目不一致\n");
return 0;
}
return 1;
}
else
{
if(0 == check(rb,n->left,level,black_level,max_black_level,max_level))
return 0;
if(0 == check(rb,n->right,level,black_level,max_black_level,max_level))
return 0;
}
}

void RBtree_check_vaild(RBtree_t rb)
{
assert(rb);
if(rb->root != rb->nil)
{
int max_black_level = 0;
int max_level = 0;
if(check(rb,rb->root,0,0,&max_black_level,&max_level))
printf("max_black_level:%d,max_level:%d\n",max_black_level,max_level);
}
}

map.h

#ifndef _MAP_H
#define _MAP_H

typedef struct map_iter
{
void *node;
struct map_iter (*next)(struct map_iter*);
void (*get_first)(struct map_iter,void*);
void (*get_second)(struct map_iter,void*);
void (*set_second)(struct map_iter,void*);
}map_iter;


extern int map_iter_equal(map_iter,map_iter);

#ifndef IT_MAP_GETFIRST
#define IT_MAP_GETFIRST(TYPE,ITER)\
({ TYPE __result;\
do ITER.get_first(ITER,&__result);\
while(0);\
__result;})
#endif

#ifndef IT_MAP_GETSECOND
#define IT_MAP_GETSECOND(TYPE,ITER)\
({ TYPE __result;\
do ITER.get_second(ITER,&__result);\
while(0);\
__result;})
#endif

#ifndef IT_MAP_SETSECOND
#define IT_MAP_SETSECOND(TYPE,ITER,VAL)\
{TYPE val=VAL;ITER.set_second(ITER,&val);}
#endif

#ifndef IT_MAP_NEXT
#define IT_MAP_NEXT(ITER)\
ITER.next(&ITER)
#endif

//能作为map存储容器的类型都必须实现的接口
struct interface_map_container
{
map_iter (*insert)(struct interface_map_container*,void*,void*);
map_iter (*erase)(struct interface_map_container*,map_iter);
void (*remove)(struct interface_map_container* rb,void*);
map_iter (*find)(struct interface_map_container* rb,void *);
map_iter (*begin)(struct interface_map_container* rb);
map_iter (*end)(struct interface_map_container* rb);
int (*size)(struct interface_map_container*);
int (*empty)(struct interface_map_container*);
void (*destroy)(struct interface_map_container**);
};

//相等返回0,小于返回-1,大于返回1
typedef int (*comp)(void*,void*);
typedef struct map *map_t;

//创建一个map,如果最后一个参数传0,则默认使用红黑树
map_t map_create(unsigned short key_size,unsigned short val_size,comp _comp,struct interface_map_container*);
void map_destroy(map_t*);

inline extern map_iter map_insert(map_t,void*,void*);
inline extern map_iter map_erase(map_t,map_iter);
inline extern void map_remove(map_t,void*);
inline extern map_iter map_find(map_t,void *);
inline extern map_iter map_begin(map_t);
inline extern map_iter map_end(map_t);
inline extern int map_size(map_t);
inline extern int map_empty(map_t);

#ifndef MAP_INSERT
#define MAP_INSERT(KEY_TYPE,VAL_TYPE,MAP,KEY,VAL)\
({ map_iter it;KEY_TYPE key = KEY;VAL_TYPE val = VAL;\
do it = map_insert(MAP,&key,&val);\
while(0);\
it;})
#endif

#ifndef MAP_REMOVE
#define MAP_REMOVE(KEY_TYPE,MAP,KEY)\
{ KEY_TYPE key = KEY;map_remove(MAP,&key);}
#endif

#ifndef MAP_FIND
#define MAP_FIND(KEY_TYPE,MAP,KEY)\
({ map_iter it;KEY_TYPE key = KEY;\
do it = map_find(MAP,&key);\
while(0);\
it;})
#endif

#endif

map.c

#include "map.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "RBtree.h"

struct map
{
struct interface_map_container *container;
int free_container_on_destroy;
};

map_t map_create(unsigned short key_size,unsigned short val_size,comp _comp,struct interface_map_container *container)
{
map_t m = malloc(sizeof(*m));
if(!m)
return 0;
if(container)
{
m->container = container;
m->free_container_on_destroy = 0;
}
else
{
m->container = (struct interface_map_container *)RBtree_create(key_size,val_size,_comp);
if(!m->container)
{
free(m);
return 0;
}
m->free_container_on_destroy = 1;
}
return m;
}

void map_destroy(map_t *m)
{

}

inline map_iter map_insert(map_t m,void *key,void *val)
{
assert(m);
return m->container->insert(m->container,key,val);
}

inline map_iter map_erase(map_t m,map_iter it)
{
assert(m);
return m->container->erase(m->container,it);
}

inline void map_remove(map_t m,void *key)
{
assert(m);
m->container->remove(m->container,key);
}

inline map_iter map_find(map_t m,void *key)
{
assert(m);
return m->container->find(m->container,key);
}

inline map_iter map_begin(map_t m)
{
assert(m);
return m->container->begin(m->container);
}

inline map_iter map_end(map_t m)
{
assert(m);
return m->container->end(m->container);
}
inline int map_size(map_t m)
{
assert(m);
return m->container->size(m->container);
}
inline int map_empty(map_t m)
{
assert(m);
return m->container->empty(m->container);
}

int map_iter_equal(map_iter a,map_iter b)
{
return a.node == b.node;
}

test.c

#include "RBtree.h"
#include <stdio.h>


int compare(void *left,void *right)
{
int l = *(int*)left;
int r = *(int*)right;
if( l == r)
return 0;
else if(l < r)
return -1;
return 1;
}


int main()
{

map_t m = map_create(sizeof(int),sizeof(int),compare,0);
int i = 9;
for( ; i >= 0; --i)
{
MAP_INSERT(int,int,m,i,i);
}

map_iter it = map_begin(m);
map_iter end = map_end(m);
for( ; !map_iter_equal(it,end); it = IT_MAP_NEXT(it))
printf("%d\n",IT_MAP_GETFIRST(int,it));

return 0;
}











posted @ 2012-04-02 09:12  sniperHW  阅读(1853)  评论(13编辑  收藏  举报