本篇介紹另外一個在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;
}