我已经实现了一个双重哈希来存储和查找整数。要存储的项目总数约为5k。为此,首先我将malloc大小为~10K的数据库。要创建条目,首先我调用find函数。如果返回的地址具有值' 0'即空插槽,然后插入项目。插入有效。但是,对于删除和修改,查找功能有时会失败。当发生以下事件序列时会发生这种情况。
entry1插入索引10中。 entry2插入索引20中。 entry3在索引10处首次发生碰撞,然后在索引20处发生秒碰撞,最后在索引30处插入了entry3。 然后entry2被删除。 现在,对entry3的查找返回索引20,但这个地方没有值。因此修改/删除失败。
您能否建议如何编写正确的查找功能?我无法找到终止do-while循环的条件而不使用"(* entry) - > key!= 0"检查。
谢谢。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="jackpot jack-1"></div>
<div class="jackpot jack-2"></div>
<div class="jackpot jack-3"></div>
<div class="jackpot jack-4"></div>
<div class="jackpot jack-5"></div>
<div class="jackpot jack-6"></div>
</div>
<button class="play"> Play </button>
PS:我可以根据以下事实引入不同的查找函数:如果哈希表中没有条目,那么查找最终将完成一个圆圈,索引将匹配start_index,此时我可以终止搜索吗?请参阅下面的代码。
#define DB_HASH_LEN 10009
typedef struct node_ {
u_int32_t key;
} hashnode_t;
int
vnid_db_open()
{
u_int32_t db_size = DB_HASH_LEN * sizeof(*db_start);
db_start = malloc(db_size);
if (db_start == NULL) {
return 0;
} else {
memset(db_start, 0, db_size);
return 1;
}
}
static inline u_int32_t
get_hash_index(u_int32_t key, u_int32_t hash_len)
{
return (key % hash_len);
}
static inline u_int32_t
get_hash_offset(u_int32_t key, u_int32_t hash_len)
{
return (1 + ((key/hash_len) % (hash_len - 1)));
}
void
find_entry(u_int32_t key, hashnode_t **entry)
{
u_int32_t index = get_hash_index(key, DB_HASH_LEN);
u_int32_t offset = get_hash_offset(key, DB_HASH_LEN);
do {
*entry = db_start + index;
index = (index + offset) % DB_HASH_LEN;
} while ((*entry)->key != 0 && (*entry)->key != key);
}
int
main(void)
{
hashnode_t *node = NULL;
u_int32_t op, key;
vnid_db_open();
while (1) {
printf("op:");
scanf("%d", &op);
getchar();
printf("key:");
scanf("%d", &key);
getchar();
switch (op) {
case(0):
find_entry(key, &node);
if (node->key == 0) {
node->key = key;
printf("inserted %d\n", key);
} else if (node->key == key) {
printf("key %d exists for insert\n", key);
} else {
printf("key %d not found for insert\n", key);
}
break;
case(1):
find_entry(key, &node);
if (node->key == key) {
node->key = 0;
printf("deleted %d\n", key);
} else {
printf("key not found %d for delete\n", key);
}
break;
case(2):
find_entry(key, &node);
if (node->key == key) {
printf("found %d\n", key);
} else {
printf("key not found %d for lookup\n", key);
}
break;
default:
break;
}
fflush(stdin);
}
return 0;
}
bash-3.2$ ./a.out
op:0
key:11111111
index 1121 offset 1111
inserted 11111111
op:0
key:11111112
index 1122 offset 1111
inserted 11111112
op:0
key:11111113
index 1123 offset 1111
inserted 11111113
op:0
key:2111113
index 9223 offset 211
inserted 2111113
op:0
key:2111114
index 9224 offset 211
inserted 2111114
op:0
key:2111114
index 9224 offset 211
key 2111114 exists for insert
op:0
key:2111115
index 9225 offset 211
inserted 2111115
op:0
key:9223
index 9223 offset 1 index 9224 offset 1 index 9225 offset 1 index 9226 offset 1
inserted 9223
op:1
key:2111113
index 9223 offset 211
deleted 2111113
op:2
key:9223
index 9223 offset 1
key not found 9223 for lookup
信用:
答案 0 :(得分:1)
根据我在评论中提到的文章,您必须为&#34;已删除密钥&#34;保留一个特殊值。所以当你的搜索找到零时你的搜索不会终止。
所以零意味着&#34;未使用&#34;和#34;特殊价值&#34; (例如-1)表示&#34;已删除,因此请继续查看&#34;。具有&#34;特殊值的条目&#34;可以重复使用。
当您回到&#34;首选索引时,您必须终止搜索&#34;你开始搜索的地方。这意味着没有找到&#34;当搜索和&#34;表满了&#34;插入时。
查看文章了解详情。