一个简单的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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言的哈希表(hashmap)可以通过数组和链表的结合实现。 首先,我们需要定义一个结构体来表示哈希表的节点,包含一个键和一个值。例如: ``` typedef struct Node { int key; int value; struct Node* next; } Node; ``` 接下来,我们需要定义一个数组作为哈希表的桶(bucket),桶的数量通常选择为一个质数,以减少冲突的概率。例如: ``` #define BUCKET_SIZE 100 // 创建一个指向Node指针数组的指针 Node** hashMap = NULL; // 初始化哈希表 void init() { hashMap = (Node**)malloc(BUCKET_SIZE * sizeof(Node*)); for (int i = 0; i < BUCKET_SIZE; i++) { hashMap[i] = NULL; } } ``` 为了实现哈希函数,我们可以使用取余操作符(%),将键映射到桶的索引上。例如,我们可以使用键的整数值除以桶的大小,并取余运算来计算索引: ``` int hash(int key) { return key % BUCKET_SIZE; } ``` 接下来,我们可以实现插入和查找操作。 插入操作首先需要先检查键是否存在于哈希表中,如果存在,则更新值;如果不存在,则创建新节点,并将节点添加到对应桶的链表上。例如: ``` void insert(int key, int value) { int index = hash(key); Node* node = hashMap[index]; // 查找节点 while (node != NULL) { if (node->key == key) { node->value = value; // 更新值 return; } node = node->next; } // 创建新节点 node = (Node*)malloc(sizeof(Node)); node->key = key; node->value = value; node->next = hashMap[index]; hashMap[index] = node; } ``` 查找操作首先计算键的哈希值,并遍历对应桶上的链表,直到找到与给定键相等的节点或链表末尾。例如: ``` int get(int key) { int index = hash(key); Node* node = hashMap[index]; // 查找节点 while (node != NULL) { if (node->key == key) { return node->value; // 返回值 } node = node->next; } return -1; // 没有找到 } ``` 此外,我们还可以实现删除操作和释放内存的函数,确定哈希表是否需要动态调整大小等。 以上就是C语言实现哈希表的简单示例。哈希表在C语言中非常常用,可以用于解决快速查找和插入的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值