结构定义如下: (注:实现方式有很多种,这只是其中一种,但大体思路都差不多)
typedef struct {
void* data;
unsigned int len;
}chashdatum;
struct chashcell {
unsigned int func;
chashdatum key;
chashdatum value;
struct chashcell* next;
};
typedef struct {
unsigned int count;
unsinged int size;
chashcell** cells;
}chash;
typedef chashiter chashcell;
#define DEFAULT_HASH_SIZE 12
#define CHASH_MAXDEPTH 3
哈希表的函数实现:
chash* hash_new(int size)
{
chash* hash = (chash*)malloc(sizeof(chash));
if (NULL == hash)
return NULL;
if (size < DEFAULT_HASH_SIZE )
size = DEFAULT_HASH_SIZE;
hash->cells = (strcut chashcell**)malloc(size * sizeof(struct chashcell* ));
if (NULL == hash->cells)
{
free(hash);
return NULL;
}
hash->count = 0;
hash->size = size;
return hash;
}
unsigned int chash_func(const char* key, unsigned int len)
{
register unsigned int c = 5381;
register const char* k = key;
while (len --)
{
c = ( (c<<5) + c) + *k++;
}
return c;
}
int chash_get(chash* hash, chashdatum* key, chashdatum* result)
{
chashiter* iter;
unsigned int func = chash_func(key->data, key->len );
iter = hash->cells[func % hash->size];
while (iter)
{
if (iter->key.len == key->len && func == iter->func && !memcmp(iter->key.data, key->data, key->len))
{
*result = iter->value;
return 0;
}
iter = iter->next;
}
return -1;
}
int chash_set(chash* hash, chashdatum* key, chashdatum* value)
{
int count = hash->count + 1;
if ( count > hash->size * CHASH_MAXDEPTH)
{
int r = chash_resize(hash, (hash->count / CHASH_MAXDEPTH) * 2 + 1);
if (r < 0)
retrurn -1;
}
unsigned int func = chash_func(key->data, key->len);
unsigned int indx = func % hash->size;
chashiter* iter = hash->cells[index];
chashiter* cell = NULL;
while(iter)
{
if (iter->key.len == key->len && func == iter->func && !memcmp(iter->key.data, key->data, key->len))
{
iter->value = value;
return 0;
}
iter = iter->next;
}
cell = (struct chashcell*) malloc (sizeof(struct chashcell));
if (NULL == cell)
return -1;
cell->key.data = key->data;
cell->key.len = key->len;
cell->value.data = value->data;
cell->value.len = value->len;
cell->func = func;
cell->next = hash->cells[indx];
hash->cells[indx] = cell;
hash->count++;
return 0;
}
int chash_resize(chash* hash, unsigned int size)
{
strcut chashcell** cells;
chashiterl* iter, *next;
unsigned int indx, nindx;
if (size == hash->size)
return 0;
cells = (struct chashcell**)malloc(size * sizeof(struct chashcell*));
if (NULL == cells)
return -1;
for (indx = 0; indx < hash->size; indx++)
{
iter = hash->cells[indx];
while (iter)
{
next = iter->next;
nindx = iter->func % size;
iter->next = cells[nindx];
cells[nindx] = iter;
iter = next;
}
}
free(hash->cells);
hash->cells = cells;
hash->size = size;
return 0;
}
void chash_free(chash* hash)
{
int indx;
chashiter* iter, *next;
for (indx = 0; indx < hash->size; indx++)
{
iter = hash->cells[indx];
while (iter)
{
next = iter->next;
free(iter);
iter = next;
}
}
free(hash->cells);
free(hash);
}
int chash_delete(chash* hash, chashdatum* key)
{
unsigned int func = chash_func(key->data, key->len);
int indx = func % hash->size;
chashiter* iter = hash->cells[indx];
while (iter)
{
if (iter->key.len == key->len && iter->func == func && !memcmp(iter->key.data, key->data, key->len) )
{
chash->cells[indx] = iter->next;
free(iter);
chash->count--;
return 0;
}
iter = iter->next;
}
return -1;
}
void chash_clear(chash* hash)
{
int indx;
chashiter* iter;
for(indx = 0; indx < hash->size; indx++)
{
iter = hash->cells[indx];
while (iter)
{
next = iter->next;
free(iter);
iter = next;
}
}
memset(hash->cells, 0, hash->size * sizeof( struct chashcell*) );
hash->count = 0;
}
chashiter* chash_begin(chash* hash)
{
chashiter* iter;
int indx = 0;
iter = hash->cells[indx];
while (!iter)
{
indx++;
if (indx >= hash->size)
return NULL;
iter = hash->cells[indx];
}
return iter;
}
chashiter* chash_next(chash* hash, chashiter* iter)
{
int indx = iter->func % hash->size;
if (!iter)
return NULL;
iter = iter->next;
while(!iter)
{
indx++;
if (indx >= hash->size)
return NULL;
iter = hash->cells[indx];
}
return iter;
}
int chash_count(chash* hash)
{
return hash->count;
}
int chash_size(chash* hash)
{
return hash->size;
}
void chash_key(chashiter* iter, chashdatum* result)
{
*result = iter->key;
}
void chash_value(chashiter* iter, chashdatum* result)
{
*result = iter->value;
}