hashtable
来源:互联网 发布:mac珊瑚红口红效果图 编辑:程序博客网 时间:2024/05/21 03:15
点击打开链接
hash.h
--------------------------------------
#ifndef _LINUX_GHASH_H_
#define _LINUX_GHASH_H_
#include <string.h>
#ifndef __USE_ISOC99
#define inline
#endif
#define create_hashtable(hsize) \
hash_create(lh_strhash, equal_str, hsize)
unsigned int lh_strhash(void *src);
int equal_str(void *k1, void *k2);
struct hashentry;
struct _hashtable;
typedef struct _hashtable hashtable;
hashtable *hash_create(unsigned int (*keyfunc)(void *),
int (*comparefunc)(void *,void *),
int size);
void hash_free(hashtable *tab);
void hash_insert(void *key, void *data, hashtable *tab);
void hash_remove(void *key, hashtable *tab);
void *hash_value(void *key, hashtable *tab);
void hash_for_each_do(hashtable *tab, int (cb)(void *, void *));
int hash_count(hashtable *tab);
#endif
hash.c
--------------------------------------
#include <string.h>
#ifdef DMALLOC
#include <dmalloc.h>
#else
#include <stdlib.h>
#endif
#include "hash.h"
#ifndef __USE_ISOC99
#define inline
#endif
struct hashentry
{
void *key;
void *data;
struct hashentry *next;
};
struct _hashtable
{
unsigned int (*gethash)(void *);
int (*compare)(void *, void *);
int hashsize;
int count;
struct hashentry **hashlist;
};
#define hashindex(key, tab) ((tab->gethash)(key) % (tab->hashsize -1))
unsigned int lh_strhash(void *src)
{
int i, l;
unsigned long ret = 0;
unsigned short *s;
char *str = (char *)src;
if (str == NULL)
return(0);
l = (strlen(str) + 1) / 2;
s = (unsigned short *)str;
for (i = 0; i < l; i++)
ret ^= s[i]<<(i&0x0f);
return(ret);
}
int equal_str(void *k1, void *k2)
{
return (0 == strcmp((char *)k1, (char *)k2));
}
inline struct hashentry *hashentry_new(void *key, void *data)
{
struct hashentry *new = malloc(sizeof(struct hashentry));
new->key = key;
new->data = data;
new->next = NULL;
return new;
}
void hlist_append(struct hashentry **root, void *key, void *data)
{
struct hashentry *l, *pos;
l = hashentry_new(key, data);
if (*root == NULL) {
*root = l;
} else {
for(pos = *root; pos->next != NULL; pos = pos->next);
pos->next = l;
}
}
int hlist_update(struct hashentry *root, void *key, void *data,
int (*compare)(void *, void *))
{
struct hashentry *pos;
for(pos = root; pos != NULL; pos = pos->next ) {
if ( compare(key, pos->key) ) {
free(pos->data);
pos->data = data;
free(key);
return 0;
}
}
return -1;
}
inline struct hashentry *hashentry_free(struct hashentry *h)
{
struct hashentry *next = h->next;
free(h->key);
free(h->data);
free(h);
h = NULL;
return (next);
}
int hlist_remove(struct hashentry **root, void *key,
int (*compare)(void *,void *))
{
struct hashentry *pos ,*prev;
if (NULL == *root) return -1;
if (compare((*root)->key, key)) {
*root = hashentry_free(*root);
return 0;
}
prev = *root;
for (pos = prev->next; NULL != pos; pos = pos->next) {
if (compare(pos->key, key)) {
prev->next = hashentry_free(pos);
return 0;
}
prev = pos;
}
return -1;
}
hashtable *hash_create(unsigned int (*keyfunc)(void *),
int (*comparefunc)(void *, void *),
int size)
{
int len = sizeof(struct hashentry *) * size;
int i;
hashtable *tab = malloc( sizeof(hashtable) );
memset(tab, 0, sizeof(hashtable));
tab->hashlist = malloc(len);
if (tab->hashlist == NULL) {
free(tab);
return NULL;
}
memset(tab->hashlist, 0, len );
for (i = 0; i < size; i++)
tab->hashlist[i] = NULL ;
tab->compare = comparefunc;
tab->gethash = keyfunc;
tab->hashsize = size;
tab->count = 0;
return tab;
}
void hash_free(hashtable *tab)
{
int i;
struct hashentry *pos;
for (i = 0; i < tab->hashsize; i++)
for (pos = tab->hashlist[i]; NULL != pos; pos = hashentry_free(pos));
free(tab->hashlist);
free(tab);
tab =NULL;
}
void hash_insert(void *key, void *data, hashtable *tab)
{
unsigned int index = hashindex(key, tab);
struct hashentry *root = tab->hashlist[index];
if ( hlist_update(root, key, data, tab->compare ) != 0 ) { //(1)
hlist_append(&(tab->hashlist[index]), key, data );
tab->count++;
}
}
//(1) 查看Hash Table中是否存在键值为key的项,如果有则替换该键值所对应的value,否则调用hlist_append为key, data生成新的hashentry并插入相应的队列中。
void hash_remove(void *key, hashtable *tab)
{
unsigned int index = hashindex(key, tab);
if (hlist_remove(&(tab->hashlist[index]), key, tab->compare) == 0) {
tab->count--;
}
}
void *hash_value(void *key, hashtable *tab)
{
struct hashentry *pos;
unsigned int index = hashindex(key, tab);
for (pos = tab->hashlist[index]; NULL != pos; pos = pos->next) {
if (tab->compare(key, pos->key)) {
return (pos->data);
}
}
return NULL;
}
void hash_for_each_do(hashtable *tab, int(cb)(void *, void *))
{
int i = 0;
struct hashentry *pos;
for (i = 0; i < tab->hashsize; i++) {
for (pos = tab->hashlist[i]; NULL != pos; pos = pos->next ) {
cb(pos->key, pos->data);
}
}
}
inline int hash_count(hashtable *tab)
{
return tab->count;
}
test.c
--------------------------------------
#ifdef DMALLOC
#include <dmalloc.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include "hash.h"
#define maxhash 10
int work(void *key, void *data)
{
printf("%s->%s\n",(char *)key, (char *)data);
return 0;
}
int main(int argc, char *argv[])
{
int i;
char key[20];
char data[20];
memset(key, 0, 20);
memset(data, 0, 20);
hashtable *tab = create_hashtable(10);
for (i = 0; i < maxhash; i++) {
sprintf(key, "key%d", i);
sprintf(data, "the line no: %d", i);
hash_insert((void *)strdup(key), (void *)strdup(data), tab);
}
printf("remove key4\n");
hash_remove("key4", tab);
printf("key -> value\n");
for (i = 0; i < maxhash; i++) {
sprintf(key, "key%d", i);
printf("%s->%s\n", key, (char *)hash_value(key, tab));
}
printf("\n");
printf("%s->%s\n", "this is ", (char *)hash_value("this is ", tab));
printf("\n");
hash_for_each_do(tab, work);
printf("size %d\n", hash_count(tab));
hash_free(tab);
exit(0);
}
编译运行
--------------------------------------
$ gcc test.c hash.c
$ ./a.out
remove key4
key -> value
key0->the line no: 0
key1->the line no: 1
key2->the line no: 2
key3->the line no: 3
key4->(null)
key5->the line no: 5
key6->the line no: 6
key7->the line no: 7
key8->the line no: 8
key9->the line no: 9
this is ->(null)
key6->the line no: 6
key1->the line no: 1
key0->the line no: 0
key9->the line no: 9
key3->the line no: 3
key8->the line no: 8
key2->the line no: 2
key5->the line no: 5
key7->the line no: 7
size 9
调用函数hash_create()之后创建一个Hash Table
------------------------------------------------------
hashtable
|---------------|
| gethash() -| lh_strhash()
| compare() -| equal_str()
| hashsize -| size
| count -| 0
| **hashlist -|------>|------------------|
|---------------| --|struct hashentry *| NULL
|------------------|
| |
|------------------|
| |
|------------------|
| |
|------------------|
| |
|------------------|
|struct hashentry *| NULL
|------------------|
调用函数hash_insert()时如果出现冲突,则形成hashentry队列
------------------------------------------------------
hashtable
|-------------|
| gethash() | lh_strhash()
| compare() | equal_str()
| hashsize | size
| count | 2
| **hashlist -|---->|------------------|
|-------------| |struct hashentry *| NULL
|------------------|
| |
|------------------| hashentry hashentry
| |-->|---------| |---------|
|------------------| | *key -| | *key -|
| | | *data --| | *data --|
|------------------| | *next --|-->| *next --| NULL
| | |---------| |---------|
|------------------|
|struct hashentry *| NULL
|------------------|
- HashTable
- Hashtable
- HashTable
- hashtable
- Hashtable
- HashTable
- hashtable
- HashTable
- Hashtable
- Hashtable
- Hashtable
- Hashtable
- hashtable
- Hashtable
- hashtable
- HashTable
- HashTable
- HashTable
- 【BZOJ】1009 [HNOI2008]GT考试 KMP+DP+矩阵优化
- 树莓派网线连接电脑进行操作
- linux上tomcat启动问题
- SqlClr —— 一次查询多个DB
- 【51nod】1270 数组的最大代价
- hashtable
- JavaSE基础练习
- postgresql技巧
- CocosCreator 创建全局对象 == 同单例效果一致
- org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access
- vue2-highcharts
- 【Miller-Rabin 素数判定】HDU
- web前端pc,mobile复制粘贴功能的实现
- (二)http协议了解