使用字符串键问题的哈希表插入实现

时间:2018-12-26 16:00:19

标签: c hashtable

我有一个问题已经尝试了好几天了。我尝试从三个结构创建一个Hashtable,第一个结构使用指针存储桶,该指针指向具有键和值对的对数组。该键应该是字符串(char * arr)。我不完全了解如何为其创建工作的插入函数,我打算在代码中尝试查看存储区h中是否存在键。我的逻辑和语法有问题。如果有人可以帮助我,将不胜感激。

我研究了Wikipedia和youtube视频上的哈希表理论,但没有一个使用三种结构和字符串键。那就是我被困住的地方。

a.operator+(b)

具有字符串键的三个结构层哈希表的有效插入函数。

1 个答案:

答案 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映射中的字符串!!!请记住,您的地图已拥有。