hash.h
typedef struct hash_item hash_item;
typedef struct hashing hashing;
hash_item *hash_get(hashing * self, void *);
hash.c
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "hash.h"
hashing * init_hash(
hashing * self,
int length,
int (*hash_fun) (void *),
int (*key_cmp) (void *, void *),
hash_item * (*item_copy) (hash_item *))
{
int i;
assert(length >= 2);
assert(hash_fun != NULL);
assert(key_cmp != NULL);
assert(item_copy != NULL);
self->list = (hash_item **) malloc(length * sizeof(hash_item *));
for (i = 0; i < length; i++) {
self->list[i] = NULL;
}
self->length = length;
self->hash_fun = hash_fun;
self->key_cmp = key_cmp;
self->item_copy = item_copy;
self->hash_add = hash_add;
self->hash_get = hash_get;
return self;
}
hashing *hash_add(hashing * self, hash_item * item)
{
int h;
hash_item *p, *new_item;
assert(self != NULL && item != NULL);
h = self->hash_fun(item->key);
assert(h < self->length);
new_item = self->item_copy(item);
new_item->next = NULL;
p = self->list[h];
if (p == NULL) {
self->list[h] = new_item;
} else {
while (p->next != NULL) {
p = p->next;
}
p->next = new_item;
}
return self;
}
hash_item * hash_get(hashing * self, void *key)
{
int h;
hash_item *p;
assert(self != NULL && key != NULL);
h = self->hash_fun(key);
assert(h < self->length);
p = self->list[h];
/* p!=NULL && key_cmp(p->key) can't reserve */
while (p != NULL && self->key_cmp(p->key, key)) {
p = p->next;
}
if (p == NULL) {
return NULL;
}
return p;
}
int str_hash_fun(void *key, int length)
{
int h, l, i;
char *str_key;
assert(key != NULL && length > 1);
str_key = (char *)key;
l = strlen(str_key);
h = 0;
for (i = 0; i < l; i++) {
h = (h + str_key[i]) % length;
}
return h;
}
hash_test.c
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "hash.h"
#define LIST_LEN 47
int my_hash_fun(void *key)
{
assert(key!=NULL);
return str_hash_fun(key, LIST_LEN);
}
int str_hash_key_cmp(void * key1, void * key2)
{
assert(key1!=NULL && key2 != NULL);
return strcmp(key1,key2);
}
hash_item * my_item_copy(hash_item * x)
{
hash_item * y;
assert(x!=NULL);
y = (hash_item *)malloc(sizeof(hash_item));
assert(y != NULL);
y->key = strdup((char*)x->key);
y->data = (int *)malloc(sizeof(int));
*((int *)(y->data)) = *((int *)(x->data));
y->next = NULL;
return y;
}
#define STRS 10
char * my_strs[STRS] = {
"hello", "go", "to", "pig", "dog",
"pear", "apple", "nut", "bananer", "orange"
};
#define STRC 4
char *co_strs[STRC] = {
"apple", "bananer", "pig", "go"
};
void main(void)
{
int i, k;
hash_item M, *item_p;
hashing *hashing_p;
hashing_p = (hashing *)malloc(sizeof(hashing));
assert(hashing_p!=NULL);
init_hash(hashing_p, LIST_LEN, my_hash_fun, str_hash_key_cmp, my_item_copy);
M.data = (int *)malloc(sizeof(int));
for(item_p = &M, i = 0; i < STRS; i++)
{
fprintf(stdout, "%s is the No. %d in list, No. %d item\n", my_strs[i], my_hash_fun(my_strs[i]), i);
item_p->key = my_strs[i];
*((int *)(item_p->data)) = i;
hashing_p->hash_add(hashing_p, item_p);
}
fprintf(stdout, "\n init end\n\ncheck out date\n");
for(i = 0; i<STRC; i++)
{
item_p = hashing_p->hash_get(hashing_p, co_strs[i]);
assert(item_p!=NULL);
k = *((int *)(item_p->data));
fprintf(stdout, " %s is the No. %d item\n", co_strs[i], k );
fprintf(stdout, "item_p = %p\n",item_p);
}
return ;
}
Makefile
gcc hash.c hash_test.c -o hash_test