/**
采用双向循环链表实现HASH表
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define RS_OK 0
#define RS_WRONG 1
#define MAX_LEN 128
#define FUNCTION_SHOW printf("this is %s, %d\n", __FUNCTION__, __LINE__);
/*双向循环链表结点*/
typedef struct list {
struct list *next;
struct list *prev;
int key;
int data;
}list;
/*hash表数据结构*/
typedef struct hash {
/*hash桶的大小*/
int bucket_size;
/*初始化时共申请bucket_size块list结构
每一个list都是一个冲突链的头结点。
*/
struct list *buckets;
}hash;
void list_print(struct list *head)
{
list *node;
FUNCTION_SHOW
if (!list_empty(head))
return;
node = head->next;
while (node != head) {
printf ("%d\n", node->key);
node = node->next;
}
return;
}
/*初始化双向循环链表*/
void list_init(struct list *head)
{
FUNCTION_SHOW
if (head == NULL)
return;
head->next = head;
head->prev = head;
}
/*删除双向循环链表*/
int destroy_list(struct list *head)
{
int i;
struct list *node, *tmp;
FUNCTION_SHOW
#ifdef RECURSION
if (head->next = head)
return RS_OK;
node = head->next->next;
free(head->next);
head->next = NULL;
destroy_list(node);
return RS_OK;
#endif
node = head->next;
while (node != head) {
tmp = node->next;
free(node);
node = NULL;
node = tmp;
}
return RS_OK;
}
/*判断链表是否为空*/
int list_empty(struct list *head)
{
FUNCTION_SHOW
if (head == NULL)
return RS_WRONG;
else if (head->next == head)
return RS_OK;
else
return RS_WRONG;
}
/*将数据插入链表尾*/
void list_insert_tail(struct list *head, struct list *node)
{
FUNCTION_SHOW
list *oldnode = NULL;
if (node == NULL ||head == NULL ) {
return;
}
oldnode = head->prev;
oldnode ->next = node;
node->prev = oldnode;
head->prev = node;
node->next = head;
list_print(head);
return ;
}
/*删除结点*/
void list_remove(struct list *node)
{
list *oldnode;
FUNCTION_SHOW
if (node == NULL) {
return ;
}
oldnode = node->prev;
oldnode->next = node->next;
node->next->prev = oldnode;
}
/*删除所有和KEY值相同的链表结点*/
void list_remove_data(struct list *head, int key)
{
list *node, *tmp;
FUNCTION_SHOW
if ((node == NULL) || (head == NULL)
||(head->prev == head)) {
return ;
}
node = head->next;
while (node != head) {
tmp = node->next;
if (node->key == key) {
list_remove(node);
free(node);
}
node = tmp;
}
}
/*创建hash表*/
struct hash *hash_create(int bucket_size)
{
int i;
hash *hashtable = NULL;
FUNCTION_SHOW
hashtable = malloc(sizeof(hash));
if (hashtable == NULL) {
hashtable = malloc(sizeof(hash));
if (hashtable == NULL)
return NULL;
}
hashtable->bucket_size = bucket_size;
hashtable->buckets = malloc((sizeof(list) * bucket_size));
if (hashtable->buckets == NULL) {
hashtable->buckets = malloc((sizeof(list) * bucket_size));
free(hashtable);
return NULL;
}
for (i=0; i < bucket_size; i++) {
list_init(&hashtable->buckets[i]);
}
return hashtable;
}
/*hash函数,采用除数留余法*/
int hash_hasher(struct hash *hash, int key)
{
int addr;
FUNCTION_SHOW
addr = key%hash->bucket_size;
return addr;
}
/*创建hash结点*/
list *create_hash_node(int key)
{
list *hashnode;
FUNCTION_SHOW
hashnode = malloc(sizeof(list));
if (hashnode == NULL)
return;
hashnode->key = key;
hashnode->prev = NULL;
hashnode->next = NULL;
return hashnode;
}
/*插入新的hash结点*/
int hash_insert(struct hash *hash, int key)
{
list *hashnode;
FUNCTION_SHOW
hashnode = create_hash_node(key);
list_insert_tail(&hash->buckets[ hash_hasher(hash, key)], hashnode);
return RS_OK;
}
/*删除hash结点*/
int hash_remove(struct hash *hash, int key)
{
FUNCTION_SHOW
list_remove_data(&hash->buckets[ hash_hasher(hash, key)], key);
return RS_OK;
}
/*hash 查找*/
int hash_lookup(struct hash *hash, int key)
{
list *head, *node, *tmp;
FUNCTION_SHOW
head = &hash->buckets[hash_hasher(hash, key)];
if (!list_empty(head))
return;
node = head->next;
while (node != head) {
tmp = node->next;
if (node->key == key) {
printf ("the node key is %d\n", node->key);
return RS_OK;
}
node = tmp;
}
return RS_WRONG;
}
/*删除hash表*/
int destory_hash_table(hash *hash)
{
int i;
for (i=0; i < hash->bucket_size; i++) {
FUNCTION_SHOW
if (destroy_list(&hash->buckets[i])) {
printf ("destroy list error\n");
}
}
free(hash->buckets);
hash->buckets = NULL;
free(hash);
hash = NULL;
}
/*测试用例*/
int main(int argc, char *argv[])
{
int i;
struct hash *hashtable;
hashtable = hash_create(MAX_LEN);
for (i=0; i < MAX_LEN; i++) {
printf("insert %d\n", i);
if(hash_insert(hashtable, i)) {
printf ("insert error\n");
return RS_WRONG;
}
}
for (i=0; i < MAX_LEN; i++) {
if (hash_lookup(hashtable, i)) {
printf ("hash lookup error\n");
}
}
destory_hash_table(hashtable);
hashtable = NULL;
return RS_OK;
}