算法参考《算法导论》第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\n", str[i], i);
        hash_insert(h, str[i], i);
    }
    printf("\n");
    for (int i = 0; i < 10; i++) {
        int value;
        bool result = hash_search(h, str[i], &value);
        printf("查找关键字:%s的结果:%s,value:%d\n", str[i], result ? "true" : "false", value);
        hash_delete(h, str[i]);
        result = hash_search(h, str[i], &value);
        printf("删除关键字:%s的结果:%s\n", str[i], result ? "false" : "true");
    }
    hash_destroy(h);
    return 0;
}