算法参考《算法导论》第11章散列表。采用链地址法解决冲突.
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <strings.h> /*通过链接法解决碰撞*/ typedef const char* hash_key_type; typedef int hash_value_type; typedef int (*hash_fun)(hash_key_type key); typedef bool (*equal_fun)(hash_key_type keya, hash_key_type keyb); typedef struct list_node_tag { hash_key_type key; hash_value_type value; struct list_node_tag *next; } list_node; typedef struct hash_tag { list_node **list_array; int num; hash_fun f; equal_fun e; } hash; hash *hash_create(int num, hash_fun f, equal_fun e){ hash *h = (hash*)malloc(sizeof(hash)); h->num = num; h->f = f; h->e = e; h->list_array = (list_node**)calloc(sizeof(list_node*), num); for (int i = 0; i < num; i++) { h->list_array[i] = NULL; } return h; } void hash_destroy(hash *h){ for (int i = 0; i < h->num; i++) { for(list_node * p = h->list_array[i]; p != NULL; ){ list_node * q = p; p = p -> next; free(q); } }; free(h->list_array); free(h); } void hash_insert(hash *h, hash_key_type key, hash_value_type value){ list_node *x = (list_node*)malloc(sizeof(list_node)); x->key = key; x->value = value; int hval = h->f(key) % h->num; x->next = h->list_array[hval]; h->list_array[hval] = x; } bool hash_search(hash *h, hash_key_type key, hash_value_type *value){ int hval = h->f(key) % h->num; list_node *x = h->list_array[hval]; while (x != NULL && !h->e(x->key, key)) { x = x->next; } if(x != NULL){ *value = x->value; return true; } else { return false; } } void hash_delete(hash *h, hash_key_type key){ int hval = h->f(key) % h->num; list_node **head = &h->list_array[hval]; list_node *x = *head; list_node *prev = NULL; while(x != NULL && !h->e(x->key , key)){ prev = x; x = x->next; } if(h->e(x->key, key)){ if(prev == NULL){ h->list_array[hval] = x->next; } else { prev->next = x->next; } free(x); } } int hash_key_fun(hash_key_type key){ const char *str = (const char*)key; int seed = 131; int hash = 0; while (*str){ hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } typedef struct node_tag{ char *str; struct node_tag *next; } node; bool str_equal(const char *a, const char *b){ return strcmp(a, b) == 0; } int main(){ hash *h = hash_create(10, hash_key_fun, str_equal); const char *str[10] = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}; for (int i = 0; i < 10; i++) { printf("key:%s,value:%d ", str[i], i); hash_insert(h, str[i], i); } printf(" "); for (int i = 0; i < 10; i++) { int value; bool result = hash_search(h, str[i], &value); printf("查找关键字:%s的结果:%s,value:%d ", str[i], result ? "true" : "false", value); hash_delete(h, str[i]); result = hash_search(h, str[i], &value); printf("删除关键字:%s的结果:%s ", str[i], result ? "false" : "true"); } hash_destroy(h); return 0; }