我正在开发一个项目,我们将使用给定的头文件编写哈希表。到目前为止一切正常(我得到了错误,但我至少可以修复),但我遇到了一个问题。我不知道如何重新打开一个开放的寻址哈希表。我将提供我的结构,我的创建函数和我的put函数。
/// The "buckets" in the table
typedef struct Entry_t {
void* key; ///< key must be "hashable"
void* value; ///< value can be any type
} Entry;
/// The hash table
typedef struct Table_t {
Entry** table; ///< table of Entry pointers
size_t size; ///< number of entries in table
size_t capacity; ///< total capacity of table
long (*hash)(void* key); ///< hash function for key
bool (*equals)(void *key1, void* key2); ///< equals function for key comparison
void (*print)(void *key, void* value); ///< print function for table dump debug
size_t collisions; ///< number of collisions throughout life of hash table
size_t rehashes; ///< number of rehashes throughout life of hash table
} Table;
Table* create(long (*hash)(void* key), bool (*equals)(void* key1, void* key2),
void (*print)(void* key1, void* key2))
{
Table* t = (Table*)malloc(sizeof(Table));
if (t == NULL)
{
return NULL;
}
t->size = 0;
t->capacity = INITIAL_CAPACITY;
t->collisions = 0;
t->rehashes = 0;
t->table = (Entry**)calloc(t->capacity, sizeof(Entry*));
t->hash = hash;
t->equals = equals;
t->print = print;
return t;
}
我编写代码的方式,t-&gt; table [index]为null,所以在插入值之前我必须使用malloc空间。这是我的put函数。
void* put(Table* t, void* key, void* value) // Rehashing needs to be completed
{
int index = t->hash(key) % t->capacity;
void* old_value = NULL;
int check = 0;
if (t->table[index] != NULL)
{
while (check == 0)
{
if (t->table[index] != NULL)
{
if (t->equals(t->table[index]->key, key) == 0)
{
index = (index + 1) % t->capacity;
}
else // Meaning the keys match, then leave
{
check = 1;
}
}
else // Empty node, meaning the key is NOT in the table
{
check = 1;
}
}
}
if (t->table[index] != NULL) // Meaning the key is in the table, so update the value
{
old_value = t->table[index]->value;
t->table[index]->value = value;
}
else
{
t->size++;
if ((float)t->size / t->capacity > LOAD_THRESHOLD) // Time to rehash
{
// Not sure what to do here
// I was told that I must use realloc, but I am unsure how
}
t->table[index] = malloc(sizeof(Entry));
t->table[index]->key = key;
t->table[index]->value = value;
t->print(key, value);
}
return old_value;
}
首先,在if测试中,看看我是否应该重新进行,我想用
重新分配内存 t->table = (Entry**)realloc((t->capacity * RESIZE_FACTOR), sizeof(Entry));
然而这给了我错误
error: passing argument 1 of 'realloc' makes pointer from integer without a cast [-Werror]
我不确定如何修复/接近。
还有将键/值对重新分配给新索引的问题,因为我相信一旦容量发生变化,表中的当前索引就不再具有代表性了。就像realloc一样,我不确定如何做到这一点。
非常感谢任何帮助,谢谢!
答案 0 :(得分:0)
size_t是一个整数。传递给realloc的第一个参数应该是一个指针。
void * realloc(void * ptr,size_t size);
您需要将指针传递给realloc,而不是t-&gt; capacity
答案 1 :(得分:0)
“还存在将键/值对重新分配给新索引的问题,因为我相信一旦容量发生变化,表中的当前索引将不再具有代表性。就像重新分配一样,我不确定如何执行此操作。 “
是的,如果您想使用新容量,则必须更改哈希函数,因此索引不再具有代表性。这就是malloc()
比realloc()
更适合这种情况的原因。
可以通过以下步骤简单地调整哈希表的大小:
评论:
realloc()
在这种情况下没有用,因为散列函数已更改,您对保留指针的位置不感兴趣。要获得更好的参考,您可以检查领先的程序员是如何完成的,例如Python的字典实现(使用C):How are Python's Built In Dictionaries Implemented?和source code。