![](/img/trans.png)
[英]How can I fix the swapBack function to get the result I intended?
[英]How can I fix this resize function?
我正在學習數據結構。 我需要為哈希表(鏈接/存儲桶)創建一個調整大小的函數。 我的代碼可以編譯,但是表大小從未改變。 有人可以看一下並給我一些有關調整大小功能中缺少的提示嗎? 謝謝!
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()期間,請小心管理舊表的鏈接列表分配。 可以在新表中重新使用它們,但是在此處進行正確的編碼可能會很困難。
以下是一些增強的想法...
PS還推薦
if (ht->count > (ht->tableSize * 8))
代替
if ((ht->count / (double) ht->tableSize) > 8.0)
PS還建議不要將桌子的大小增加一倍,而應增加四倍。 此外,將表的大小設置為素數也很不錯。 用質數執行“%ht-> tableSize”有助於改善弱哈希函數的散布。
添加hashTableDelete()時,四倍效果很好。 使用delete函數,您可以再次調用resize函數,但是這次表正在縮小。 重要的是您的增長閾值(例如tablesize * 8)和收縮閾值必須不同。 如果兩者差不多,則當表具有該臨界大小時,如果您恰好要添加和刪除,則可能會出現“散列混亂”的情況。 我喜歡將增長閾值設置為3、11、61、251,...(素數低於4 ** N),將收縮閾值設置為1、7、31、119,...(素數低於2 * 4 ** N),因此隨着表的增長和收縮,將重新哈希保持在最低水平。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.