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