上一篇: iOS標準庫中經常使用數據結構和算法之二叉排序樹算法
系統提供一個全局的key爲字符串的哈希表。並提供哈希表的建立、元素添加、元素查找、哈希表的銷燬的能力。存儲在哈希表中的元素是一個以下的標準結構:bash
//哈希表元素實體結構定義
typedef struct entry {
char *key; //哈希表中的key,必須是字符串
void *data; //哈希表中的值,是一個指針類型,其內容能夠任意。
} ENTRY;
複製代碼
功能:用於全局哈希表的建立和銷燬操做。數據結構
頭文件:#include <search.h>數據結構和算法
平臺:BSD Unix函數
函數簽名:oop
//建立一個哈希表
int hcreate(size_t nel);
//銷燬一個哈希表
void hdestroy(void);
複製代碼
參數:post
nel: [in]指定哈希表的初始容量尺寸,這個參數主要用於內存存儲上的優化處理。優化
return:[out] 若是哈希表建立成功則返回0,不然返回非0。spa
描述:指針
系統提供了一個全局的哈希表,所以這也是一個很是重要的缺點,由於咱們沒法知道其餘函數是否也正在使用這個哈希表。所以在特定時刻只有一個哈希表是有效的。我的的感受是這就是一個很是不合理的哈希表實現。
功能:用於哈希表元素的添加和查詢。
頭文件:#include <search.h>
平臺:BSD Unix
函數簽名:
ENTRY * hsearch(ENTRY item, ACTION action);
複製代碼
參數:
item:[in] 要進行查詢或者添加的條目,這是一個ENTRY類型的數據。若是咱們只是查詢則只須要設置ENTRY中的key部分的值,而若是是添加則須要設置完整的key和data的值。
action:[in]指定要對哈希表執行的動做,這個類型是一個ACTION類型的枚舉值,其定義以下:
typedef enum {
FIND, ENTER
} ACTION;
複製代碼
當值設置爲FIND時則只進行查找處理。 當值設置爲ENTER是就先進行查找,若是不存在時就進行添加處理。
return:[out] 返回查找或者添加時在哈希表中的實體元素的指針。若是沒有查找到或者添加失敗則返回NULL。咱們不須要對返回的ENTRY指針進行內存釋放處理,而是由系統來完成。
描述:
對哈希表執行ENTER動做時,若是找到了則直接返回之前曾經插入到哈希表中的條目,若是沒有找到則會在哈希表中建立一個新的條目,並返回新條目的指針。**這裏須要注意的是在執行插入時要求ENTRY結構體中的key部分的內存必需要用malloc進行分配,由於哈希表在銷燬時會對全部哈希表中的元素的key部分調用free處理。**也就是說對於哈希表的插入來講key的內存咱們負責分配,而由系統負責銷燬。這裏也存在一個BUG就是當咱們對一個在哈希表中已經存在的key再次調用hsearch時會返回對應的ENTRY指針。可是咱們沒法得知這個返回值究竟是新建立的仍是已經存在的。而咱們的key又是經過malloc分配出來的內存數據,所以就沒法肯定咱們是否須要去釋放這部分已經分配出來的key的內存。
示例代碼:
void main()
{
//建立
if (hcreate(10) != 0)
{
//插入
ENTRY ent;
ent.key = malloc(4); //對於插入處理必須用malloc進行內存分配,並且咱們不須要去釋放它。
ent.data = (int*)10; //這裏值保存着整數類型。
strcpy(ent.key, "Bob");
ENTRY *p1 = hsearch(ent, ENTER);
NSAssert(strcmp(p1->key, "Bob")==0, @"oops!");
ent.key = malloc(6);
ent.data = (int*)20;
strcpy(ent.key, "Alice");
ENTRY *p2 = hsearch(ent, ENTER);
//查找
ENTRY *p3 = hsearch(ent, FIND);
NSAssert(p3 == p2);
//銷燬
hdestroy();
}
}
複製代碼
因爲這個哈希表的實現對插入重複元素時存在着BUG,以及又是全局惟一的,因此不建議使用它。