注:修改完善于一个粗糙版本http://blog.csdn.net/aishen944/article/details/1483516
1,修改了原文代码中的错误
2,主要解决了在扩容时hash效率较差的问题
#ifndef _HASHTABLE_H
#define _HASHTABLE_H
struct hashtable;
struct hashtable* hashtable_create(unsigned long size, unsigned long(*hash_func)(const void *key),
int(*test_func)(const void *key1, const void *key2));
struct hashtable* make_string_hashtable(unsigned long size);
int hashtable_put(struct hashtable *ht, const void *key, void *value);
void* hashtable_get(struct hashtable *ht, const void *key);
int hashtable_remove(struct hashtable *ht, const void *key);
int hashtable_contains(struct hashtable *ht, const void *key);
int hashtable_set(struct hashtable *ht, const void *key, void *newvalue);
unsigned long hashtable_count(struct hashtable *ht);
void hashtable_map(struct hashtable *ht, int(*mapfunc)(void*, void*, void*), void*);
void hashtable_clear(struct hashtable *ht);
void hashtable_close(struct hashtable *ht);
#endif
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <iostream>
using namespace std;
// #include "hashtable.h"
/* Hashtable MAX fullness, you can amend it, but it may best, i think. */
#define HASH_MAX_FULLNESS 0.75
#define HASH_RESIZE_FACTOR 2
#define HASH_POSITION(key, hash_func, size) ((hash_func)(key) % size)
/* Because linuxget hashtable allow 0/NULL key. So we use -1 to point
empty hash mapping. */
#define INVALID_PTR ((void*) ~(unsigned long)0)
#define INVALID_PTR_BYTE 0xff
#define NON_EMPTY(mapping) ((mapping)->key != INVALID_PTR)
typedef unsigned long (*hash_func_t)(const void *key);
typedef int (*test_func_t)(const void *key1, const void *key2);
struct hash_mapping {
void *key;
void *value;
};
//可以替换上面的宏
inline unsigned long hash_position(const void *key,hash_func_t hash_func,unsigned long size)
{
return hash_func(key)%size;
}
inline bool non_empty(hash_mapping * mapping)
{
return (mapping->key != INVALID_PTR);
}
struct hashtable {
hash_func_t hash_func; /* Hash function pointer. */
test_func_t test_func; /* Hash key compare function pointer. */
struct hash_mapping *mappings; /* Hashtable data entries. */
unsigned long count; /* Current hashtable not NULL en