map容器的c实现
来源:互联网 发布:alpine linux 包管理 编辑:程序博客网 时间:2024/04/29 14:55
原文来自:http://blog.chinaunix.net/uid-21457204-id-3063180.html
主要是使用红黑树这种数据结构封装一个MAP容器,本来想模仿STL MAP,不过现在暂时实现,今后会改进,目前还没实现加锁这功能,不过可以支持win32和linux平台。。。
以下是源代码:
- /*
- * file: main.c
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2012-01-31
- */
- #define DEBUG
- #include <stdio.h>
- #include <time.h>
- #include <stdlib.h>
- #include <string.h>
- #include "map.h"
- #ifdef DEBUG
- #define dump(a,s) __dump((a),(s))
- #else
- #define dump(a,s)
- #endif
- typedef struct word_info {
- unsigned long hash_major;
- unsigned long hash_minor;
- char *path;
- unsigned long line;
- unsigned long col;
- }word_info_t;
- typedef struct priv_info {
- unsigned long key;
- char val[10];
- }priv_info_t;
- static void __dump(priv_info_t *array, size_t num)
- {
- int i;
- printf("-- DUMP START -- \n");
- for (i=0; i< num; i++)
- {
- printf("array[%d].key=%03d, array[%d].val=%s\n",
- i, array[i].key, i,array[i].val);
- }
- printf("-- DUMP END -- \n");
- }
- #define map_info(pm){\
- printf("-- dump map start ... --\n");\
- map_dump(pm);\
- printf("-- dump map end ... --\n");\
- }
- #define ARRAY_SIZE(a)(sizeof(a)/sizeof(a[0]))
- #define MAX_NUM 20
- int main()
- {
- map_t map1;
- int key;
- int i, j;
- priv_info_t priv_info[MAX_NUM];
- srand(time(0));
- memset(priv_info, 0, sizeof(priv_info));
- for (i=0; i<MAX_NUM; i++)
- {
- key = rand()%MAX_NUM;
- priv_info[i].key= key;
- sprintf(priv_info[i].val,"i am %d", key);
- }
- dump(priv_info, ARRAY_SIZE(priv_info));
- map_init(&map1);
- i = 0;
- while (i< MAX_NUM)
- {
- struct mnode* node;
- printf("-- %d -- \n", i);
- node = map_find(&map1,&(priv_info[i].key),NULL);
- if (!node){
- printf("->>> insert node: priv_info[%d].key=%d \n", i, priv_info[i].key);
- map_insert_alloc(&map1,&(priv_info[i].key),
- &priv_info[i], sizeof(priv_info[i]),NULL);
- } else {
- /* key not matched, so just print out */
- printf("priv_info[%d].key=%d is exist!\n", i, priv_info[i].key);
- for (j=0; j< MAX_NUM; j++){
- if(priv_info[j].key== priv_info[i].key&& i!=j)
- printf("\t|-- priv_info[%d].key=%d\n", j, priv_info[j].key);
- }
- }
- map_info(&map1);
- i++;
- }
- map_info(&map1);
- printf("-----------------------------------\n");
- for (i=0; i< MAX_NUM; i++)
- {
- struct mnode* node;
- node = map_find(&map1,&i,NULL);
- if (node){
- map_remove_free(&map1,&i, NULL);
- printf("--> key=%03d deleted!\n", i);
- map_info(&map1);
- }else{
- printf("key=%03d not found!\n", i);
- }
- }
- map_info(&map1);
- map_exit(&map1);
- return 0;
- }
.............................................................................................
.............................................................................................
- /*
- * file: map.h
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2012-01-31
- */
- #ifndef __MAP_H__
- #define __MAP_H__
- #include <stdlib.h>
- #include "platform.h"
- #include "rbtree.h"
- #define lock_t int
- #define lock_init(x)
- #define lock_exit(x)
- #ifndef NULL
- #define NULL 0
- #endif
- #define __assert(x)
- #define __free(x) free(x)
- #define __malloc(x) malloc(x)
- #define __memcpy(d,s,len) memcpy((d),(s),(len))
- extern struct map;
- typedef int (*CMP_FUNC)(const void*d1, const void *d2);
- typedef struct mnode{
- struct rb_node node;
- void *key;
- void *private;
- }mnode_t;
- /*
- typedef struct ops{
- struct mnode*(*find)(struct map*map, void *key, CMP_FUNC cmpf);
- int (*insert_alloc)(struct map*map, void *key,
- void *private, size_t size, CMP_FUNC cmpf);
- int (*remove_free)(struct map*map, void *key, CMP_FUNC cmpf);
- int (*insert)(struct map*map, struct mnode*data, CMP_FUNC cmpf);
- int (*remove)(struct map*map, void *key, CMP_FUNC cmpf);
- }ops_t;
- */
- typedef struct map{
- struct rb_root root;
- lock_t lock;
- }map_t;
- extern int map_init(struct map* map);
- extern int map_exit(struct map* map);
- struct mnode* __rbfind(struct map*map, void *key, CMP_FUNC cmpf);
- int __rbinsert_alloc(struct map*map, void *key,
- void *private, size_t size, CMP_FUNC cmpf);
- int __rbremove_free(struct map*map, void *key, CMP_FUNC cmpf);
- int __rbinsert(struct map*map, struct mnode*data, CMP_FUNC cmpf);
- int __rbremove(struct map*map, void *key, CMP_FUNC cmpf);
- #define map_find(map,key,cmpf)\
- __rbfind((map),(key),(cmpf))
- #define map_insert_alloc(map,key,priv,size,cmpf)\
- __rbinsert_alloc((map),(key),(priv),(size),(cmpf))
- #define map_remove_free(map,key,cmpf)\
- __rbremove_free((map),(key),(cmpf))
- #if 0
- #define map_insert(map,data,cmpf)\
- __rbinsert((map),(data),(cmpf))
- #define map_remove(map,key,cmpf)\
- __rbremove((map),(key),(cmpf))
- #endif
- #define map_entry(ptr, type, member) container_of(ptr, type, member)
- extern struct mnode *map_first(const struct map*map);
- extern struct mnode *map_last(const struct map*map);
- extern struct mnode *map_next(const struct mnode*mnode);
- extern struct mnode *map_prev(const struct mnode*mnode);
- extern void map_dump(const struct map* map);
- #endif
.............................................................................................
- /*
- * file: map.c
- * author: vincent.cws2008@gmail.com
- * history:
- * initial @ 2012-01-31
- */
- #define DEBUG
- #include "map.h"
- #define mnode_init(mnode){\
- (mnode)->node.rb_parent_color=0;\
- (mnode)->node.rb_right=0;\
- (mnode)->node.rb_left=0;\
- (mnode)->key=0;\
- (mnode)->private=0;\
- }
- void map_dump(const struct map* map)
- {
- struct mnode *mnode;
- int cnt=0;
- for (mnode= map_first(map); mnode; mnode= map_next(mnode))
- printf("key=%03d%s",*(int*)mnode->key,++cnt%10==0?"\n":" ");
- printf("\n");
- }
- static int __cmp_default(long*d1, long *d2)
- {
- // printf("-- d1:%d, d2:%d\n",*d1, *d2);
- if (*d1< *d2) return-1;
- else if(*d1 > *d2) return 1;
- else return 0;
- }
- struct mnode* __rbfind(struct map*map, void *key, CMP_FUNC cmpf)
- {
- int result;
- CMP_FUNC cmp;
- struct mnode *data;
- struct rb_node *node = map->root.rb_node;
- __assert(map && key);
- cmp = cmpf ? cmpf: __cmp_default;
- /* printf("==> entry %s key:%d\n", __func__,*(int*)key);*/
- while (node)
- {
- data = container_of(node, struct mnode, node);
- /* printf("data->key:%d VS key:%d\n",*(int*)(data->key),*(int*)key);*/
- result = cmp(key, data->key);
- /*printf("result=%d, node->rb_left=%p, node->rb_right=%p\n",
- result, node->rb_left, node->rb_right);*/
- if (result< 0)
- node = node->rb_left;
- else if(result > 0)
- node = node->rb_right;
- else
- return data;
- }
- //printf("node=%p\n", node);
- return NULL;
- }
- int __rbinsert(struct map*map, struct mnode*data, CMP_FUNC cmpf)
- {
- int result;
- struct mnode *this;
- CMP_FUNC cmp;
- struct rb_node **new= &(map->root.rb_node),*parent = NULL;
- __assert(map && data);
- cmp = cmpf ? cmpf: __cmp_default;
- /* Figure out whereto put new node */
- while (*new)
- {
- this = container_of(*new, struct mnode, node);
- result = cmp(data->key, this->key);
- parent = *new;
- if (result< 0) new = &((*new)->rb_left);
- else if(result > 0) new= &((*new)->rb_right);
- else return -2;
- }
- /* Add new nodeand rebalance tree.*/
- rb_link_node(&(data->node), parent, new);
- rb_insert_color(&(data->node),&(map->root));
- return 0;
- }
- int __rbremove(struct map*map, void *key, CMP_FUNC cmpf)
- {
- struct mnode* data = __rbfind(map, key, cmpf);
- __assert(map && key);
- if (data)
- rb_erase(&(data->node),&(map->root));
- return 0;
- }
- int __rbinsert_alloc(struct map*map, void *key,
- void *private, size_t size, CMP_FUNC cmpf)
- {
- struct mnode *new;
- __assert(map && key&& private);
- new = (struct mnode*)__malloc(size+sizeof(struct mnode));
- __assert(new);
- mnode_init(new);
- new->key= key;
- new->private= new+1;
- if (private)
- __memcpy(new->private,private, size);
- return __rbinsert(map, new, cmpf);
- }
- int __rbremove_free(struct map*map, void *key, CMP_FUNC cmpf)
- {
- struct mnode* data;
- __assert(map && key);
- data = __rbfind(map, key, cmpf);
- /* printf("%s: key: %d\n", __func__,*(int*)(data->key));*/
- if (data)
- {
- /* printf("%s: deleted!\n", __func__);*/
- rb_erase(&(data->node),&(map->root));
- __free(data);
- }
- return 0;
- }
- struct mnode *map_first(const struct map*map)
- {
- struct rb_node *node;
- __assert(map);
- node = rb_first(&(map->root));
- if(node)
- return map_entry(node, struct mnode, node);
- return NULL;
- }
- struct mnode *map_last(const struct map*map)
- {
- struct rb_node *node;
- __assert(map);
- node = rb_last(&(map->root));
- if(node)
- return map_entry(node, struct mnode, node);
- return NULL;
- }
- struct mnode *map_next(const struct mnode*mnode)
- {
- struct rb_node *node;
- __assert(mnode);
- node = rb_next(&(mnode->node));
- if(node)
- return map_entry(node, struct mnode, node);
- return NULL;
- }
- struct mnode *map_prev(const struct mnode*mnode)
- {
- struct rb_node *node;
- __assert(mnode);
- node = rb_prev(&(mnode->node));
- if(node)
- return map_entry(node, struct mnode, node);
- return NULL;
- }
- int map_init(struct map* map)
- {
- map->root.rb_node= NULL;
- lock_init(map->lock);
- return 0;
- }
- int map_exit(struct map* map)
- {
- lock_exit(map->lock);
- return 0;
- }
- map容器的c实现
- map容器的c实现
- 使用C++STL的map容器实现一种命令映射
- c++<map>容器的方法
- 【C++】map容器的使用方法
- c++map容器的基本用法
- C++--vector<>容器,List<>链表,map<>容器的用法
- c++map容器介绍
- C++MAP关联容器
- C++map容器类
- C++map容器复习
- C++map容器用法
- C++map关联容器
- c++map容器介绍
- C/C++知识要点2——STL中Vector、Map、Set容器的实现原理
- 文本查询程序(c++)set,vector,map容器实现
- C语言--容器的实现。
- C++:map容器和pair的结合使用
- WM_Paint 消息详解
- UBUNTU 11.10 (32位)双网卡 NAT 实现局域网共享上网
- 数据库中为什么要有恢复子系统?它的功能是什么?
- 深度探索WM_PAINT消息
- 转 英文操作系统下输入温度单位(ºC)的问题
- map容器的c实现
- tomcat虚拟路径的配置
- 开放创新、合作共赢、全力推进中国游戏产业健康发展
- 回忆那么重、思念那么痛
- 马化腾:拥抱移动互联网 开放共赢
- struts入门
- git-daemon安装
- AJAX学习笔记:创建XMLHttpRequest对象的五步骤
- 数据库并发控制