關於哈希表與鏈式哈希表的描述能夠參閱:http://www.cnblogs.com/idreamo/p/7990860.htmlhtml
鏈式哈希表的操做與屬性有:初始化、銷燬、插入元素、刪除元素、查找元素、獲取哈希表中無數的個數。數組
chtbl_init數據結構
int cltbl_init(CHTbl *htbl, int buckts, int (*h)(const void *key), int (*match)(const void *key1,const void *key2), void (*destroy)(void *data));函數
返回值:若是哈希表初始化成功,返回0,不然返回-1。編碼
描述: 初始化htbl指定的鏈式哈希表。spa
在對鏈式哈希表執行其餘操做以前,必需要先初始化。哈希表中所分配的「桶」的個數將由buckets指定。函數指針h指向一個用戶定義的哈希函數,此函數會將鍵進行散列。函數指針match指向一個用戶定義的函數,此函數用於判斷兩個鍵是否匹配。若是key1等於key2,返回1;不然返回其餘值。參數destroy是一個函數指針,經過調用chtbl_destroy來釋放動態分配的內存空間。若是哈希表中的數據不須要釋放,那麼destroy應該指向NULL。 指針
複雜度: O(m),m是哈希表中「桶」的個數。code
chtbl_destroy
htm
void cltbl_destroy(CHTbl *htbl);blog
返回值:無。
描述: 銷燬htbl指定的鏈式哈希表。
在調用chtbl_destroy以後再也不容許進行其餘操做,除非再次調用chtbl_init。chtbl_destroy會刪除哈希表中的全部元素,並同時釋放chtbl_init中參數destroy不爲NULL的成員所佔用的內存空間。
複雜度: O(m),m是哈希表中「桶」的個數。
chtbl_insert
int cltbl_insert(CHTbl *htbl,const void *data);
返回值:若是插入元素成功則返回0;若是哈希表中已經包含此元素,返回1;不然返回-1。
描述: 向htbl指定的鏈式哈希表中插入一個元素。
新元素包含一個指向data的指針,只要元素仍然存在於哈希表中,此指針就一直有效。與data相關的內存空間將由函數的調用者來管理。
複雜度: O(m),m是哈希表中「桶」的個數。
chtbl_remove
int cltbl_remove(CHTbl *htbl,const void **data);
返回值:若是刪除元素成功則返回0;不然返回-1。
描述: 從htbl指定的鏈式哈希表中刪除與data匹配的元素。
返回時data指向已經刪除元素中存儲的數據。與data相關的內存空間將由函數的調用者來管理。
複雜度: O(1)
chtbl_lookup
int cltbl_lookup(const CHTbl *htbl,const void **data);
返回值:若是在哈希表中找到元素則返回0;不然返回-1。
描述: 查找htbl指定的鏈式哈希表中與data相匹配的元素。
若是找到,在函數返回時,data將指向哈希表中相匹配元素中的數據。
複雜度: O(1)
chtbl_size
int cltbl_size(CHTbl *htbl);
返回值:哈希表中的元素個數。
描述: 獲取htbl指定的鏈式哈希表的元素個數的宏。
複雜度: O(1)
#ifndef CHTBL_H #define CHTBL_H #include <stdlib.h> #include "list.h" /*爲哈希表定義一個數據結構*/ typedef struct CHTbl_ { int buckets; /*一、表中分配的「桶」的個數*/ int (*h)(const void *key); /*二、指向哈希函數*/ int (*match)(const void *key1, const void *key2); /*三、指向match函數*/ int (*destroy)(void *data); /*四、指向銷燬函數*/ int size; /*五、表中元素的數量*/ List *table; /*六、存儲「桶」的數組*/ }CHTbl; /*公用接口*/ int chtbl_init(CHTbl *htbl, int buckets, int(*h)(void *key), int (*match)(const void *key1, const void *key2), void(*destroy)(void *data)); int 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_H
示例:鏈式哈希表的實現
#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; /*首先,爲「桶」分配空間*/ if((htbl->table = (List *)malloc(buckets*sizeof(List)))==NULL) return -1; /*而後,調用list_init初始化這些桶*/ htbl->buckets = buckets; for(i=0;i<htbl->buckets;i++) list_init(&htbl->table[i],destroy); /*接着,封裝h,match,destroy函數*/ htbl->h = h; htbl->match = match; htbl->destroy = destroy; /*最後,將size值設置爲0*/ htbl->size = 0; return 0; } /*chtbl_destroy 銷燬鏈式哈希表*/ void chtbl_destroy(CHTbl *htbl) { int i; /*首先,刪除每一個「桶」中的元素*/ for(i=0;i<htbl->buckets;i++) { list_destroy(&htbl->table[i]); } /*而後,釋放由chtbl_init分配的內存空間*/ free(htbl->table); /*最後,哈希表再也不容許任何操做,清除這一結構做爲錯誤預防*/ memset(htbl,0,sizeof(CHTbl)); return ; } /*chtbl_insert 向鏈式哈希表中插入元素*/ int chtbl_insert(CHTbl *htbl,const void *data) { void *temp; int bucket,retval; /*首先,調用chtbl_lookup檢查哈希表中是否已經存有該元素*/ temp = (void *)data; if(chtbl->lookup(htbl,&temp)==0) return 1; /*若是未存有該元素,接着將新元素的鍵散列*/ bucket = htbl->h(data) % htbl->buckets; /*而後,根據哈希編碼將新元素插入哈希表中相應位置的「桶」中*/ 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; /*首先,哈希(散列)元素的鍵*/ bucket = htbl->h(*data)%htbl->buckets; /*接着,查找與元素的鍵相匹配的桶*/ prev = NULL; for(element = list_head(&htbl->table[bucket]);element != NULL; element = list_next(element)) { if(htbl->match(*data,list_data(element))) { /*而後,調用list_rem_next刪除元素*/ if(list_rem_next(&htbl->table[bucket],prev,data) == 0) { htbl->size--; return 0; } else { return -1; } } prev = element; } /*遍歷結束後,沒有找到元素,返回-1*/ retrun -1;}/*chtbl_lookup 查找元素*/int chtbl_lookup(const CHTbl *htbl,void **data){ ListElmt *element; int bucket; /*首先,散列要查找元素的鍵*/ bucket = htbl->h(*data) % htbl->buckets; /*接着,查找與元素相匹配的桶*/ for(element = list_head(&htbl->table[bucket]; element != NULL; list_next(element)) { if(htbl->match(*data,list_data(element)) /*從表中返回該元素*/ *data = list_data(element); return 0; } /*遍歷結束後,沒有找到元素,則返回-1*/ return -1;}