基于C语言的hash表

来源:互联网 发布:mac导入照片不清晰 编辑:程序博客网 时间:2024/06/07 18:51

哈希表可以理解成链表的变形,两者很类似,区别个人觉得在简单的在尾端插入数据的速度并没有太大区别,
在读取内容的时间差别很大,因为链表是遍历读取,而哈希表是通过hash值直接读取
以下是相关代码
hashmap.h

#ifndef __HASHMAP_H__#define __HASHMAP_H__#define bool int#ifndef TRUE#define TRUE 1#endif#ifndef FALSE #define FALSE 0 #endiftypedef struct hashmap_t hashmap;hashmap* hashmap_create(int max_bucket_num,int(*hash)(void*key),bool(*equal)(void* key1,void* key2));void* hashmap_put(hashmap* map,void* key,void* value);void* hashmap_get(hashmap* map,void* key);void hashmap_for_each(hashmap* map,bool (*callback)(void* key,void* value,void* context),void* context);void hashmap_free(hashmap* map);#endif

其中hashmap_create中可以看出有两个回调函数,hash回调函数的作用是在hashmap_put时生成唯一
的hash值,equal回调函数的作用是为了在hashmap_get 时判断是否key和哈希表中对应的值一致
hashmap.c

#include<stdio.h>#include<stdlib.h>#include"hashmap.h"typedef struct entry_t{    void* key;    void* value;    struct entry_t* next;}entry;struct hashmap_t{    entry** bucket;    int max_bucket_num;    int (*hash)(void *key);    bool (*equal)(void* key1,void* key2);     int size;};hashmap* hashmap_create(int max_bucket_num,int(*hash)(void*key),bool(*equal)(void* key1,void* key2)){    hashmap *map = (hashmap*)malloc(sizeof(hashmap));    if(map == NULL)    {        goto error;    }    map->bucket = NULL;    map->max_bucket_num = max_bucket_num;    map->bucket = (entry**)calloc(max_bucket_num,sizeof(entry*));    map->hash = hash;    map->equal = equal;    map->size = 0;    return map;    error:    return NULL;}static int hash_key(hashmap* map,void* key){    return map->hash(key);}static int hash_index(hashmap* map,int hash){    return  ((size_t) hash & (map->max_bucket_num- 1));}static bool equal_key(void* key1,void* key2,bool(*equal)(void* key1,void* key2)){    if(key1 == key2)    {        return TRUE;    }    return(equal(key1,key2));}static entry* create_entry(void* key,void* value){   entry* entry = malloc(sizeof(entry));    entry->key = key;   entry->value = value;   entry->next = NULL;   return entry;}void* hashmap_put(hashmap* map,void* key,void* value){    int h = hash_key(map,key);    int index = hash_index(map,h);    printf("h = %d\n",h);    printf("index = %d\n",index);    if(map == NULL)    {        return NULL;    }    entry** p= &(map->bucket[index]);    while(TRUE)    {        entry* current = *p;        if(current == NULL)        {            *p = create_entry(key,value);            if(*p != NULL)            {                map->size++;            }            return NULL;        }        if(equal_key(key,current->key,map->equal))        {           void* old_value = current->value;            current->value = value;           return old_value;        }        p=&current->next;    }    return (void*)0;}void* hashmap_get(hashmap* map,void* key){    int h = hash_key(map,key);    int index = hash_index(map,h);    entry* current = map->bucket[index];    for(;current != NULL;current = current->next)     {       if(equal_key(current->key,key,map->equal))       {           return current->value;       }    }    return (void*)0;}void hashmap_free(hashmap* map){    int i;    for(i = 0;i < map->max_bucket_num;i++)    {        entry* current = map->bucket[i];        while(current != NULL)        {            entry* next = current->next;            free(current);            current = next;        }    }    free(map);}void hashmap_for_each(hashmap* map,bool (*callback)(void* key,void* value,void* context),void* context){    int i;    for(i = 0;i < map->max_bucket_num;i++)    {        entry* current = map->bucket[i];        while(current != NULL)        {            callback(current->key,current->value,context);            current = current->next;        }    }}

main.c

#include<math.h>#include<stdio.h>#include<string.h>#include"hashmap.h"int hash(void* key){    int hash_num = 0;    int digit_num = 0;    for(char* p = (char*)key;p && *p;p++)    {        hash_num = ((hash_num << 5) + hash_num) + *p;    }    return hash_num;}bool equal(void* key1,void* key2){    printf("key1 = %s\n",(char*)key1);    printf("key2 = %s\n",(char*)key2);    return !strcmp((char*)key1,(char*)key2);}bool callback(void* key,void* value,void* context) {    printf("key = %s\n",(char*)key);    printf("value = %s\n",(char*)value);}int main(){    hashmap* map = hashmap_create(100,hash,equal);    char* key = "a";    char* value = "qiaotsh";    hashmap_put(map,key,value);    key = "b";    value = "chent";    hashmap_put(map,key,value);    key = "c";    value = "chent";    hashmap_put(map,key,value);    key = "d";    value = "chent";    hashmap_put(map,key,value);    key = "name1";    value = "chent";    hashmap_put(map,key,value);    key = "name2";    value = "chent";    hashmap_put(map,key,value);    void* ret = hashmap_get(map,"name2");    printf("a= %s\n",(char*)ret);    hashmap_for_each(map,callback,NULL);    hashmap_free(map);    return 0;}

执行结果如下
h = 97
index = 97
h = 98
index = 98
h = 99
index = 99
h = 100
index = 96
h = 134059282
index = 2
h = 134059283
index = 3
a= chent
key = name1
value = chent
key = name2
value = chent
key = d
value = chent
key = a
value = qiaotsh
key = b
value = chent
key = c
value = chent

原创粉丝点击