简单的哈希表实现
这是一个简单的哈希表的实现,用c
语言做的。
原理
先说一下原理。
先是有一个bucket
数组,也就是所谓的桶。
哈希表的特点就是数据
与其在表中的位置存在相关性
,也就是有关系的,通过数据应该可以计算出其位置。
这个哈希表是用于存储一些键值对(key -- value
)关系的数据,其key
也就是其在表中的索引,value
是附带的数据。
通过散列算法,将字符串的key
映射到某个桶中,这个算法是确定的,也就是说一个key
必然对应一个bucket
。
然后是碰撞问题,也就是说多个key
对应一个索引值。举个例子:有三个key
:key1
,key3
,key5
通过散列算法keyToIndex
得到的索引值都为2
,也就是这三个key
产生了碰撞,对于碰撞的处理,采取的是用链表连接起来,而没有进行再散列。
这是包含的头文件
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BUCKETCOUNT 16
哈希表和节点数据结构的定义
1 struct hashEntry 2 { 3 const char* key; 4 char* value; 5 struct hashEntry* next; 6 }; 7 8 typedef struct hashEntry entry; 9 10 struct hashTable 11 { 12 entry bucket[BUCKETCOUNT]; //先默认定义16个桶 13 }; 14 15 typedef struct hashTable table;
初始化和释放哈希表
1 //初始化哈希表 2 void initHashTable(table* t) 3 { 4 int i; 5 if (t == NULL)return; 6 7 for (i = 0; i < BUCKETCOUNT; ++i) { 8 t->bucket[i].key = NULL; 9 t->bucket[i].value = NULL; 10 t->bucket[i].next = NULL; 11 } 12 } 13 14 //释放哈希表 15 void freeHashTable(table* t) 16 { 17 int i; 18 entry* e,*ep; 19 if (t == NULL)return; 20 for (i = 0; i<BUCKETCOUNT; ++i) { 21 e = &(t->bucket[i]); 22 while (e->next != NULL) { 23 ep = e->next; 24 e->next = ep->next; 25 free(ep->key); 26 free(ep->value); 27 free(ep); 28 } 29 } 30 }
哈希散列算法
1 //哈希散列方法函数 2 int keyToIndex(const char* key) 3 { 4 int index , len , i; 5 if (key == NULL)return -1; 6 7 len = strlen(key); 8 index = (int)key[0]; 9 for (i = 1; i<len; ++i) { 10 index *= 1103515245 + (int)key[i]; 11 } 12 index >>= 27; 13 index &= (BUCKETCOUNT - 1); 14 return index; 15 }
辅助函数strDup
这是比较多余的做法,因为C标准库中string.h
中有一系列这样的函数。
1 //在堆上分配足以保存str的内存 2 //并拷贝str内容到新分配位置 3 char* strDup(const char* str) 4 { 5 int len; 6 char* ret; 7 if (str == NULL)return NULL; 8 9 len = strlen(str); 10 ret = (char*)malloc(len + 1); 11 if (ret != NULL) { 12 memcpy(ret , str , len); 13 ret[len] = '