需要帮助为双哈希实现编写查找函数

时间:2017-11-03 10:48:44

标签: c++ c hash

我已经实现了一个双重哈希来存储和查找整数。要存储的项目总数约为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
信用:

  

how to search using double hash in c

1 个答案:

答案 0 :(得分:1)

根据我在评论中提到的文章,您必须为&#34;已删除密钥&#34;保留一个特殊值。所以当你的搜索找到零时你的搜索不会终止。

所以零意味着&#34;未使用&#34;和#34;特殊价值&#34; (例如-1)表示&#34;已删除,因此请继续查看&#34;。具有&#34;特殊值的条目&#34;可以重复使用。

当您回到&#34;首选索引时,您必须终止搜索&#34;你开始搜索的地方。这意味着没有找到&#34;当搜索和&#34;表满了&#34;插入时。

查看文章了解详情。