哈希表 - 调整崩溃程序的大小

Posted

技术标签:

【中文标题】哈希表 - 调整崩溃程序的大小【英文标题】:Hash Table - resizing crashes program 【发布时间】:2020-11-28 17:03:32 【问题描述】:

我在调整哈希表大小时遇到​​问题。每当我将大小设置为更大的数字时,程序就会崩溃。但是,当我将该值设置为较小时,它不会崩溃。我认为散列函数(计算新值)可能是一个问题,但我无法准确说出原因。好吧,我认为这与索引有关。 将“旧”哈希表中的元素插入到新哈希表中工作正常,但我无法调整它的大小。 这里是resize方法的代码:

void resize()

    if (current_size >= load * size)
    
        int newsize = size * cap;
        Node** tmp = new Node * [newsize];
        for (int i = 0; i < size; i++)
        
            tmp[i] = hashtable[i];
        
        delete[] hashtable;
        hashtable = tmp;
        size = newsize; //crash

    

这里是 Node 类:

class Node

public:
string key;
V value;
Node* next;
Node* data;
Node(string key, V value)

    this->key = key;
    this->value = value;
    this->next = NULL;

Node() ;
;

和HashTable类:

class HashTable

    int size;
    int current_size;
    int cap;
    float load;
    Node **hashtable;
    HashTable()
    
        this->size = 5;
        this->current_size = 0;
        this->cap = 2;
        this->load = 0.4;
        this->hashtable = new Node*[size];

        for (int i = 0; i < size; i++)
        
            hashtable[i] = NULL;
        
    

我正在考虑为 resize 方法中的所有元素重做 addTo 方法,但我不知道这是否是问题所在。感谢您的帮助。

【问题讨论】:

那么当您离开resize() 时,您希望 hashtable[oldsize] 有什么价值? tmp 中的许多元素没有被清空,但很难说这是否是真正的原因。在没有外部帮助的情况下,resize 函数中的任何内容都不会导致崩溃。代码中的其他地方造成了致命的伤害,程序最终在resize中崩溃并死亡。 【参考方案1】:
void resize() 
    if (current_size >= load * size) 
        int newsize = size * cap;
        Node** tmp = new Node * [newsize];
        for (int i = 0; i < size; i++) 
            tmp[i] = hashtable[i];
        
        for (int i = size; i < newsize; ++i) 
            tmp[i] = nullptr;
        

        delete[] hashtable;
        hashtable = tmp;
        size = newsize; //crash

    

会解决眼前的问题,但我怀疑还有另一个错误。

您需要对所有元素进行重新散列,而不是调整大小中的代码。

【讨论】:

你将如何对所有已插入的元素进行重新散列? 编辑:这行得通,谢谢。我现在只需要重新散列所有元素。

以上是关于哈希表 - 调整崩溃程序的大小的主要内容,如果未能解决你的问题,请参考以下文章

有哪些算法可用于调整哈希表的大小?

哈希表调整大小:我们如何在不知道密钥的情况下做到这一点?

是否可以在 Perl 中保留哈希表的大小?

为啥哈希表在存储桶的数组上使用链表?

为啥将地址右移三位作为固定大小哈希表的哈希函数?

为啥哈希表扩展通常通过将大小加倍来完成?