我有一个问题已经尝试了好几天了。我尝试从三个结构创建一个Hashtable,第一个结构使用指针存储桶,该指针指向具有键和值对的对数组。该键应该是字符串(char * arr)。我不完全了解如何为其创建工作的插入函数,我打算在代码中尝试查看存储区h中是否存在键。我的逻辑和语法有问题。如果有人可以帮助我,将不胜感激。
我研究了Wikipedia和youtube视频上的哈希表理论,但没有一个使用三种结构和字符串键。那就是我被困住的地方。
a.operator+(b)
具有字符串键的三个结构层哈希表的有效插入函数。
答案 0 :(得分:0)
您的插入函数中有很多问题:
void hash_insert (HashTable *tab, const char *key, int value)
{
unsigned long h = hash(key) % tab->hash_size;
int i = 0;
// depending on how you initialise your hash table, the list might yet
// be NULL(!) - so you possibly yet need a check for!
// you need FIRST to check if the index is yet valid, THEN check
// if there is a key!
//while(tab->bucket[h]->list[i]->key != NULL && (i < tab->bucket->size))
while(i < tab->bucket[h].size && tab->bucket[h].list[i].key != NULL)
// additionally: you have a pointer, index operator [] dereferences
// -> you have a struct directly -> need to access via .
{
//Pair pair = copy_key(key,value);
// BAD idea: you malloc a struct, but never free it -> memory leak!
if (tab->bucket[h].list[i].key == /*pair->*/key)
// compare directly!
// however: == compares the pointers only - most likely, though,
// you have created a new string somewhere else just with same
// CONTENT - in this case you need to compare via strcmp:
if (strcmp(tab->bucket[h].list[i].key, key) == 0)
{
//tab->bucket[h]->list[i]->value == pair->value;
// comparison? assuming you wanted to assign:
tab->bucket[h].list[i].value = value;
return;
}
}
// end of while reached, the key was not yet found!
// -> you need to insert it here:
if(i == tab->bucket[h].size)
{
// no space in buckets left!
// -> need to realloc (leaving this to you)
// BUT: you might want to consider overall fill grade or maximum fill
// grade for buckets and do a complete re-hash of all contents...
}
// assuming we insert in THIS bucket:
tab->bucket[h].list[i].key = ???;
tab->bucket[h].list[i].value = value;
}
???
-好吧,取决于。我几乎假设您希望哈希图拥有它包含的键字符串。这样一来,您就可以避免本地数组超出范围,也可以避免动态分配的字符串随后被删除!所以:
tab->bucket[h].list[i].key = strdup(key);
如果由于已经分配了字符串而要避免不必要的复制,则可以添加另一个参数:int isTakeOwnwership
(或bool
,但需要#include <stdbool.h>
):>
tab->bucket[h].list[i].key = isTakeOwnership ? key : strdup(key);
在两个示例中,我都没有检查strdup的结果是否为NULL-您需要这样做并处理内存分配失败的情况(也许在插入函数中添加一个返回值,指示成功或失败?)。
别忘了在移除元素时free
映射中的字符串!!!请记住,您的地图已拥有。