簡體   English   中英

如何修復此調整大小功能?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM