source of hsearch_r
可以在網上找到。
如果該鍵是表,函數與檢查行動,這意味着將現有的關鍵行爲就像發現它之前找到的條目返回。 (您可以在調用hsearch(ADD)
之後覆蓋「found」結構的值並覆蓋舊值。)
該實現不適合元素刪除。它維護一個桶陣列。散列衝突是通過查找另一個空桶來處理的,因此存儲區索引不一定等於散列碼。當你使用相同的散列碼插入兩個值時,第二個將得到這樣一個散列碼不是存儲桶索引的存儲桶。
當您現在刪除第一個項目,然後嘗試查找第二個項目時,將不會找到它,因爲只有當散列代碼是存儲區索引已滿的「最佳」存儲區時纔會考慮「其他」存儲區。
除了非更新重新增加和缺失的刪除選項,還有其他限制hsearch_r
。例如,必須預先估計條目的最大值,並且以後不能更改。我認爲hsearch_r
旨在作爲適用於有限範圍應用的快速哈希表。用另一個更通用的哈希表實現可能會更好。
或者,您可以使用默認數據參數,意思是「不存在」。 entry->data
的類型是void *
,所以NULL
是一個明顯的選擇。下面的數據是手冊頁的與具有更自然的語法比hsearch_r
包裝功能示例的變化:
#include <stdio.h>
#include <stdlib.h>
#define _GNU_SOURCE
#define __USE_GNU
#include <search.h>
#define NIL (-1L)
void hadd(struct hsearch_data *tab, char *key, long value)
{
ENTRY item = {key, (void *) value};
ENTRY *pitem = &item;
if (hsearch_r(item, ENTER, &pitem, tab)) {
pitem->data = (void *) value;
}
}
void hdelete(struct hsearch_data *tab, char *key)
{
ENTRY item = {key};
ENTRY *pitem = &item;
if (hsearch_r(item, FIND, &pitem, tab)) {
pitem->data = (void *) NIL;
}
}
long hfind(struct hsearch_data *tab, char *key)
{
ENTRY item = {key};
ENTRY *pitem = &item;
if (hsearch_r(item, FIND, &pitem, tab)) {
return (long) pitem->data;
}
return NIL;
}
int main()
{
char *data[] = {
"apple", "pear", "cherry", "kiwi",
"orange", "plum", "pomegranate", NULL
};
char **p = data;
struct hsearch_data tab = {0};
int i;
hcreate_r(10, &tab);
for (i = 0; i < 5; i++) hadd(&tab, data[i], i + 1L);
hdelete(&tab, "pear");
hadd(&tab, "cherry", 144);
while (*p) {
long value = hfind(&tab, *p);
if (value == NIL) {
printf("%s: NIL\n", *p);
} else {
printf("%s: %ld\n", *p, value);
}
p++;
}
hdestroy_r(&tab);
return 0;
}
注:如果您使用ponters數據和哈希表擁有的數據,你必須free
的有關銷燬的數據,還有當您覆蓋現有值時。
@M Oehm,「hsearch_r」的第三個參數是包含返回值的結構,對吧?那麼,你爲什麼將它初始化爲'&item'? ps:我是一個新手,試圖使用hsearch_r – venkrao 2015-11-03 17:10:59
@venkrao:沒有必要初始化'pitem';你可以傳遞未初始化指針的地址,因爲它會被覆蓋。所以對'&item'的初始化是令人困惑的,但是很有害。如果'pitem'應該被初始化,那麼更好的值可能是'NULL'。 – 2015-11-03 17:57:36
@M歐姆,謝謝。我在我的代碼中觀察到這種奇怪的行爲,其中'hsearch_r'能夠將'ENTER'元素放入散列表中。但是,當我嘗試「查找」時,搜索失敗。隨着一些打印語句的更多調試,我意識到只有上次插入的元素停留在散列表中。其他人不是,或者他們只是被覆蓋。我很難理解爲什麼只存在一個元素(爲什麼它被覆蓋)想知道你是否看到過類似的行爲,並希望我解釋得很好。 – venkrao 2015-11-04 03:04:24