gpt4 book ai didi

c - 如何修复此调整大小功能?

转载 作者:行者123 更新时间:2023-11-30 17:51:27 26 4
gpt4 key购买 nike

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

    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);
}

最佳答案

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

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. 还建议不要将表大小增加一倍,而是增加四倍。此外,拥有最佳尺寸的 table 也是一种不错的感觉。使用素数执行“%ht->tableSize”有助于改善弱哈希函数的分散性。

当您添加 hashTableDelete() 时,四倍化有一个很好的感觉。使用删除函数,您可以再次调用调整大小函数,但这一次,表正在缩小。重要的是,您的增长阈值(例如表大小*8)和收缩阈值是不同的。如果存在大致相同的情况,那么当表达到临界大小时,如果您碰巧添加和删除,则可能会遇到“散列的颠簸”。我喜欢将增长阈值设置为 3, 11, 61, 251, ...(4**N 以下的素数),将收缩阈值设置为 1, 7, 31, 119, ...(2* 以下的素数) 4**N),因此随着表的增长和收缩,将重新散列保持在最低限度。

关于c - 如何修复此调整大小功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16722718/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com