开放寻址冲突解决方案

时间:2015-01-31 23:19:53

标签: c hash hashtable collision-detection

在使用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个特殊值: DELETED USED ,< strong> FREE 表示该位置被删除/使用/免费,我不知道如何编码这些值?

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

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

1 个答案:

答案 0 :(得分:1)

这个问题有点令人困惑,我想你并没有试图访问已经释放的内存(你的问题让我觉得你是这样)。 将enum标签添加到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;
};

只有当密钥为NULL时才会检查标签,如果没有,则会使用它。