链式哈希表的实现 发表于 2018-06-05 | 更新于 2018-06-09 | 分类于 算法 哈希算法一般用于快速查找和加密算法 chtbl.h 1234567891011121314151617181920212223242526272829303132333435363738#ifndef CHTBL_H#define CHTBL_H#include <stdlib.h>#include "list.h"/* Define a structure for chained hash tables. */typedef struct CHTbl_ {int buckets;int (*h)(const void *key);int (*match)(const void *key1, const void *key2);void (*destroy)(void *data);int size;List *table;} CHTbl;/* Public Interface. */int chtbl_init(CHTbl *htbl, int buckets, int (*h)(const void *key), int (*match)(const void *key1, const void *key2), void (*destroy)(void *data));void chtbl_destroy(CHTbl *htbl);int chtbl_insert(CHTbl *htbl, const void *data);int chtbl_remove(CHTbl *htbl, void **data);int chtbl_lookup(const CHTbl *htbl, void **data);#define chtbl_size(htbl) ((htbl)->size)#endif chtbl.m 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176#include <stdlib.h>#include <string.h>#include "list.h"#include "chtbl.h"/* chtbl_init */int chtbl_init(CHTbl *htbl, int buckets, int (*h)(const void *key), int (*match)(const void *key1, const void *key2), void (*destroy)(void*data)) {int i;/*Allocate space for the hash table.*/if ((htbl->table = (List *)malloc(buckets * sizeof(List))) == NULL) return -1;/*Initialize the buckets.*/htbl->buckets = buckets;for (i = 0; i < htbl->buckets; i++) list_init(&htbl->table[i], destroy);/*Encapsulate the functions.*/htbl->h = h;htbl->match = match;htbl->destroy = destroy;/*Initialize the number of elements in the table.*/htbl->size = 0;return 0;}/* chtbl_destroy */void chtbl_destroy(CHTbl *htbl) {int i;/*Destroy each bucket.*/for (i = 0; i < htbl->buckets; i++) { list_destroy(&htbl->table[i]);}/*Free the storage allocated for the hash table.*/free(htbl->table);/*No operations are allowed now, but clear the structure as a precaution.*/memset(htbl, 0, sizeof(CHTbl));return;}/* chtbl_insert */int chtbl_insert(CHTbl *htbl, const void *data) {void *temp;int bucket, retval;/* Do nothing if the data is already in the table. */temp = (void *)data;if (chtbl_lookup(htbl, &temp) == 0) return 1;/* Hash the key. */bucket = htbl->h(data) % htbl->buckets;/*Insert the data into the bucket.*/if ((retval = list_ins_next(&htbl->table[bucket], NULL, data)) == 0) htbl->size++;return retval;}/* chtbl_remove */int chtbl_remove(CHTbl *htbl, void **data) {ListElmt *element, *prev;int bucket;/*Hash the key.*/bucket = htbl->h(*data) % htbl->buckets;/*Search for the data in the bucket.*/prev = NULL;for (element = list_head(&htbl->table[bucket]); element != NULL; element = list_next(element)) { if (htbl->match(*data, list_data(element))) { /*Remove the data from the bucket.*/ if (list_rem_next(&htbl->table[bucket], prev, data) == 0) { htbl->size--; return 0; } else { return -1; } } prev = element;}/*Return that the data was not found.*/return -1;}/* chtbl_lookup */int chtbl_lookup(const CHTbl *htbl, void **data) {ListElmt *element;int bucket;/*Hash the key.*/bucket = htbl->h(*data) % htbl->buckets;/*Search for the data in the bucket.*/for (element = list_head(&htbl->table[bucket]); element != NULL; element = list_next(element)) { if (htbl->match(*data, list_data(element))) { /*Pass back the data from the table.*/ *data = list_data(element); return 0; }}/*Return that the data was not found.*/return -1;}