基于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=¤t->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
阅读全文
0 0
- 基于C语言的hash表
- C语言 打造最快的Hash表
- hash表 c语言实现
- hash表的openADDRESSing的c语言实现
- C语言中的两种hash表的实现
- 配合Dijkstra算法的Hash表实现文件C语言
- C语言 拉链法HASH表存储
- C语言hash函数
- C语言基于链表的栈
- C语言基于链表的队列
- 基于一致性hash算法 C++语言的实现详解
- 基于一致性hash算法 C++语言的实现详解
- 基于C语言的万年历
- 基于hash表的文件字符串替换
- 【小镇的技术天梯】从头开始写算法,C语言hash表
- 配合Dijkstra算法的Hash表头文件C语言
- 基于C语言的广义表的运算
- C语言 开放寻址法HASH表存储简单实现
- クレイジー描画ボード
- MFC画线
- java读取项目里配置文件properties的工具
- 怎么解决java.lang.NoClassDefFoundError错误
- redis.conf配置
- 基于C语言的hash表
- Go语言 --- slice切片
- 如何设置多选框使之只可以选择一项
- Android获取电池充电状态的方式
- Java Web笔记(六)
- 利用AD域访问web资源
- 怎样选择安全靠谱的网贷平台
- 原创简单易懂的排列算法,经过测试性能要比字典排序好25%左右
- 字符设备初始化