在 C++ 中删除哈希表

Posted

技术标签:

【中文标题】在 C++ 中删除哈希表【英文标题】:deleting a hash table in C++ 【发布时间】:2017-07-17 00:59:52 【问题描述】:

我正在使用由 C++ 中的链表表示的数组和存储桶构建一个哈希表。当我尝试清除哈希表时,我遇到了一些非常奇怪的事情,如果有人能解释为什么会发生这种情况,我将不胜感激。

这段代码运行良好:

for(int i = 0; i < bins; i++)

    while(map[i]->next != nullptr)
    
        LN* toDelete = map[i];
        map[i] = map[i]->next;
        delete toDelete;
    

但是由于某种原因,如果我这样做,它不会再删除任何内容:

for(int i = 0; i < bins; i++)

    LN* node = map[i]
    while(node->next != nullptr)
    
        LN* toDelete = node;
        node = node->next;
        delete toDelete;
    

每个 bucker 都由一个预告片链表表示,这就是我检查 node->next 而不是 node 的原因。根据我对指针的理解,node 应该与 map[i] 引用相同的东西,所以当我在 node 上调用 delete 时,它​​应该删除 map[i] 和 node 引用的对象。

提前谢谢你

【问题讨论】:

请edit您的问题提供minimal reproducible example。 我假设您正在做这个哈希表作为练习?否则你应该使用std::unordered_map 您的代码(两个示例)不会删除 所有 个节点,也不会删除最后一个节点。 这是一个预告片链表,所以如果它把预告片留在原地就可以了 如果map [0]nullptr 会发生什么? 【参考方案1】:

您的代码确实会删除所有内容。它没有做的是将map[i] 指针更改为最后指向一个空列表元素(next 设置为nullptr),因此它最终指向一个已删除的对象。

这意味着map[i] 悬空。取消引用它是未定义的行为。这可以通过在循环后将node 的值分配给map[i] 来解决:

LN* node = map[i];
while(node->next != nullptr)

    LN* toDelete = node;
    node = node->next;
    delete toDelete;

map[i] = node;

【讨论】:

每个桶都由一个拖车链表表示,因此如果桶中没有值,则 map[i] 应该指向一个空节点。我想我不清楚的是这段代码没有在析构函数中实现,它是用来清除链表的内容的。我的问题是说 node* = map[i] 与使用 map[i] 相同。由于某种原因,我的问题中的第二个代码块没有按预期运行。

以上是关于在 C++ 中删除哈希表的主要内容,如果未能解决你的问题,请参考以下文章

对 C++ 哈希表有一个好的哈希函数吗?

C++进阶第二十一篇——哈希(概念+哈希函数+哈希冲突+哈希表+哈希桶+代码实现)

C++ 哈希表问题

哈希表 - 链表数组 - C++

哈希表:为啥在开放寻址方案中难以删除

C++ 哈希表查询_进入哈希函数结界的世界