【问题标题】:How can I fix this resize function?如何修复此调整大小功能?
【发布时间】:2013-05-19 07:57:50
【问题描述】:

我正在学习数据结构。我需要为哈希表(链接/桶)创建一个调整大小的函数。我的代码可以编译,但表大小从未改变。有人可以看看并给我一些关于我在调整大小功能中缺少的提示吗?谢谢!

    struct hlink {
    TYPE value;
    struct hlink *next;
};

struct hashTable {
    struct hlink **table;
    int tableSize;
    int count;
};


void initHashTable (struct hashTable *ht, int size ) {
    assert (size > 0);

    //allocate memory for table 
    ht->table = (struct hlink **) malloc(size * sizeof(struct hlink *));
    assert(ht->table != 0);

    //initialize empty link list
    int i;
    for (i = 0; i < size; i++)
    {
        ht->table[i] = 0;
    }

    //set tableSize to be size
    ht->tableSize = size;
    ht->count = 0;
}


    void _resizeHashTable(struct hashTable *ht)
{
    //create and initialize new tablesize
    int new_tblSize = 2 * ht->tableSize;

    //old list
    struct hlink **oldList = ht->table;

    //new list
    struct hlink **newList = (struct hlink **) malloc(new_tblSize * sizeof(struct hlink*));

    //Copy old values to new table
    for (int i=0; i < new_tblSize; i++)
    {
        //compute hash value to find the new bucket
        int hashIndex = HASH(oldList[i]->value) % new_tblSize;
        if (hashIndex < 0)
            hashIndex += new_tblSize;

        newList[i]->value = oldList[i]->value;
        newList[i]->next = newList[hashIndex];
    }

    //Assign table and tablesize back to the old table
    free(ht->table);
    ht->table = newList;
    ht->tableSize = new_tblSize;

}


void hashTableAdd (struct hashTable *ht, TYPE newValue)
{
    // compute hash value to find the correct bucket
    int hashIndex = HASH(newValue) % ht->tableSize;
    if (hashIndex < 0)
        hashIndex += ht->tableSize;

    struct hlink * newLink = (struct hlink *) malloc(sizeof(struct hlink));
    assert(newLink != 0);

    newLink->value = newValue;
    newLink->next = ht->table[hashIndex];

    ht->table[hashIndex] = newLink;     //add to bucket 
    ht->count++;


    if ((ht->count / (double) ht->tableSize) > 8.0)
        _resizeHashTable(ht);
}

【问题讨论】:

    标签: c arrays resize linked-list hashtable


    【解决方案1】:

    您没有释放旧表。您正在释放刚刚分配的那个。而不是

    ht->table = new_tbl;
    ...
    free(new_tbl);
    

    你应该

    free(ht->table);
    ht->table = new_tbl;
    

    你也有问题

    //Copy old values to new table
    for (int i=0; i < ht->tableSize; i++)
    {
        new_tbl[i] = ht->table[i];
    }
    

    像上面那样复制表桶条目是不够的,但是桶链接列表中的每个条目都需要重新散列,因为你有一个新的表大小,因此有一个潜在的新哈希索引。

    int hashIndex = HASH(newValue) % ht->tableSize;
    

    我建议您在调整大小时暂时检查每个旧存储桶,然后检查每个链接列表条目并将其移动到新表中。请记住,对于每个条目,由于“% ht->tableSize”不同,旧表中的存储桶索引可能与新表中的存储桶条目不同。

    在 resize() 期间,请注意管理旧表的链接列表分配。它们可以在您的新表中重复使用,但在此处正确编码可能具有挑战性。

    以下只是一些增强的想法...

    P。 S.也推荐

    if (ht->count > (ht->tableSize * 8))
    

    而不是

    if ((ht->count / (double) ht->tableSize) > 8.0)
    

    P。 S. 也建议不要将桌子大小增加一倍,而是增加四倍。此外,拥有一个优质的桌子大小是一种很好的感觉。使用质数执行“%ht->tableSize”有助于改善弱散列函数的分散。

    当您添加 hashTableDelete() 时,Quadrupling 具有很好的效果。使用 delete 函数,您可以再次调用 resize 函数,但这一次,表正在缩小。重要的是您的增长阈值(例如 tablesize*8)和收缩阈值不同。如果大致相同,那么当表具有该临界大小时,如果您碰巧添加和删除,您可以获得“散列的抖动”。我喜欢将增长阈值设置为 3、11、61、251、...(质数低于 4**N),收缩阈值设置为 1、7、31、119、...(质数低于 2* 4**N),因此随着表的增长和缩小,将重新散列保持在最低限度。

    【讨论】:

    • 非常感谢您的解释。我试图重新做调整大小的功能,但我还在苦苦挣扎。我的代码编译,但大小未调整大小。我更新了我的调整大小功能。你介意给我更多提示吗?
    • @user2203774 发布更多问题或聊天
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 2014-05-09
    • 2012-04-11
    • 2011-08-23
    相关资源
    最近更新 更多