【问题标题】:open addressing collision resolution开放寻址冲突解决
【发布时间】:2015-01-31 23:19:53
【问题描述】:

我在用 c 编程语言实现开放寻址哈希表时遇到了困难:

#ifndef COMDS_OPENADDR_HASH_TABLE
#define COMDS_OPENADDR_HASH_TABLE

#define COMDS_KEY_EXIST 1
#define COMDS_REALLOC_FAIL  2

struct kv_pairs {
    void *key;
    void *value;
};

typedef struct openaddr_hash_table {
    size_t buckets;
    size_t used;
    size_t (*hash)(void *data);
    struct kv_pairs *table; 
    int (*key_equal)(void *fkey, void *skey);
    int (*value_equal)(void *fvalue, void *svalue);
}OpenAddrHashTable;
#endif

所以这里我使用了一个 struct kv_pairs 数组来保存我的键和值,问题是我必须有 3 个特殊值:DELETEDUSED、FREE 表示该位置已删除/使用/免费,我不知道如何编码这些值?

我尝试设置 struct kv_pairs 并设置 FREE 0x0 DELETED 0x1 和 USED 0x2,并进行类似的比较

table[i] == FREE || table[i] == (struct kv*)DELETED

【问题讨论】:

  • 你尝试过的有什么问题?你有什么问题(除了比较不相关的指针undefined behavior)?您是否尝试向任一结构添加标志?
  • 您无法确定在任何给定平台上肯定是无效地址值的值。所以不要去定义这三个值。相反,分配 3 个全局或静态变量,并使用它们的地址。此外,您可能想与table[i].value 进行比较(尽管从问题中很难理解)。
  • 在检查值之前,我会尝试检查 table[i] 是否空闲或已使用

标签: c hash hashtable collision-detection


【解决方案1】:

这个问题有点令人困惑,我假设您没有尝试访问已释放的内存(您的问题让我认为您是)。 向 struct kv_pair 添加枚举标签将是一个简单的解决方案

struct kv_pair {
    enum { KV_PAIR_FREE, KV_PAIR_DELETED, KV_PAIR_USED } tag;
    void *key;
    void *value;
};

或者您可以添加一个单独的标签数组(可能一起分配)到 struct openaddr_hash_table

enum tag { KV_PAIR_FREE, KV_PAIR_DELETED, KV_PAIR_USED};
struct openaddr_hash_table {
    size_t buckets;
    size_t used;
    size_t (*hash)(void *data);
    struct kv_pairs *table;
    enum tag *tags;
    int (*key_equal)(void *fkey, void *skey);
    int (*value_equal)(void *fvalue, void *svalue);
};

选择哪一种取决于常见的内存访问模式,但两者都会增加数据结构的内存使用量。第三种不增加内存(这似乎是您想要的)的解决方案可能如下:

#include <stdint.h>
#define FREE 0
#define DELETED 1

struct kv_pair {
    void *key;
    union {
        void *value;
        uintptr_t tag;
    } value;
};

只有在 key 为 NULL 时才检查标签,如果不是,则它正在使用中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    • 2012-03-01
    • 1970-01-01
    相关资源
    最近更新 更多