一个简单的HashMap C语言实现

一个简单的HashMap C语言实现

cheungmine

用C语言实现一个简单实用的hashmap,具有一定的实际意义。尤其我们不想使用STL里面的map<...>类的时候。我实现的这个hashmap,用来做key---value的映射,key必须是有效的字符串,value是调用者分配的任意类型的数据。这个hashmap适合在一些简单的场合下,消耗极少的资源。

首先定义头文件如下:

/*
*hashmap.h
*Generichashmap:key(string)-value(anytype).
*cheungmine
*Sep.22,2007.Allrightsreserved.
*/
#ifndefHASHMAP_H_INCLUDED
#define HASHMAP_H_INCLUDED

#include
" unistd.h "

/* Youshouldalwaysuse1024 */
#define HASHMAP_SIZE1024

/* Opaquestructpointerto_hash_map_t */
typedef
struct _hash_map_t * hash_map;

typedef
void ( * pfcb_hmap_value_free)( void * value);

/* Anexampleoffreevaluefunctionimplementedbycaller:
voidmy_hmap_free_value(void*pv)
{
free(pv);
}
*/


/* Createbeforeuse.eg:
*hash_maphm;
*hmap_create(&hm,HASHMAP_SIZE);
*assert(hm);//outofmemoryifhm==NULL
*void*mydata=malloc(n);
*hmap_insert(hm,"shanghai",-1,mydata);
...
*hmap_destroy(hm,my_hmap_free_value);
*/
extern void
hmap_create(hash_map
* hmap, int size);

/* Destroyafteruse */
extern void
hmap_destroy(hash_maphmap,pfcb_hmap_value_free);

/* Insertakey-valueintohashmap.valueisapointertocallee-allocatedmemory */
extern void
hmap_insert(hash_maphmap,
const char * key, int key_len /* -1forstrlentobecalled */ , void * value);

/* Searchahashmapforvalueofgivenkeystring */
extern void *
hmap_search(hash_maphmap,
const char * key);


#endif /*HASHMAP_H_INCLUDED*/

实现文件如下:

/*
*hashmap.c
*Generichashmapimplementation.
*amapforpairofkey-value.keymustbeanull-endstring,valueisanytypeofdata.
*cheungmine
*Sep.22,2007.Allrightsreserved.
*/

#include
" hashmap.h "
#include
" list.h "

typedef
struct _hash_map_t
{
size_tsize;
listnode_t
** key;
listnode_t
** value;
}hash_map_t;

/* Hashastring,returnahashkey */
static ulong hash_string( const char * s, int len)
{
ulong h = 0 ;
int i = 0 ;
assert(s);
if (len < 0 )
len
= (s ? ( int )strlen(s): 0 );
while (i ++ < len){h = 17 * h + * s ++ ;}
return h;
}

static void _free_map_key(listnode_t * node)
{
listnode_t
* old;
while (node)
{
old
= node;
node
= node -> next;

free(old
-> data);
free(old);
}
}

static void _free_map_value(listnode_t * node,pfcb_hmap_value_freepfunc)
{
listnode_t
* old;
while (node)
{
old
= node;
node
= node -> next;

if (pfunc)
(
* pfunc)(old -> data);
free(old);
}
}

/* =============================================================================
PublicFunctions
=============================================================================
*/
/* Createbeforeuse */
void
hmap_create(hash_map
* hmap, int size)
{
(
* hmap) = (hash_map_t * )malloc( sizeof (hash_map_t));
(
* hmap) -> size = size;
(
* hmap) -> key = (listnode_t ** )calloc(size, sizeof (listnode_t * ));
(
* hmap) -> value = (listnode_t ** )calloc(size, sizeof (listnode_t * ));
}

/* Destroyafteruse */
extern void
hmap_destroy(hash_maphmap,pfcb_hmap_value_freepfunc)
{
size_ti;
for (i = 0 ;i < hmap -> size;i ++ ){
_free_map_key(hmap
-> key[i]);
_free_map_value(hmap
-> value[i],pfunc);
}

free(hmap
-> key);
free(hmap
-> value);
free(hmap);
}


/* Insertakey-valueintohashmap.valueisapointertocallee-allocatedmemory */
void
hmap_insert(hash_maphmap,
const char * key, int key_len, void * value)
{
listnode_t
* node_key, * node_val;
ulong h;
char * s;
assert(key);

if (key_len < 0 )key_len = ( int )strlen(key);
s
= ( char * )malloc(key_len + 1 );
assert(s);

#pragma warning(push)/*C4996*/
#pragma warning(disable:4996)
strncpy(s,key,key_len);
#pragma warning(pop)/*C4996*/
s[key_len]
= 0 ;

node_key
= list_node_create(( void * )s);
node_val
= list_node_create(value);
assert(node_key
&& node_val);

h
= hash_string(s,key_len) % hmap -> size;

node_key
-> next = hmap -> key[h];
hmap
-> key[h] = node_key;

node_val
-> next = hmap -> value[h];
hmap
-> value[h] = node_val;
}

/* Searchahashmapforvalueofgivenkeystring */
void *
hmap_search(hash_maphmap,
const char * key)
{
ulong h = hash_string(key, - 1 ) % hmap -> size;
listnode_t
* pk = hmap -> key[h];
listnode_t
* pv = hmap -> value[h];

while (pk)
{
if (strcmp(key,pk -> str) == 0 )
return pv -> data;
pk
= pk -> next;
pv
= pv -> next;
}

return NULL;
}

好了,其中用到的其他文件(unistd.h,list.h,list.c)看我下一篇文章!

C语言实现一个简单的单向链表list

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值