如何解决陷入重新哈希我在 C 中使用 Hashtable 实现的字典
我已经用c语言实现了这个哈希表字典。它在没有重新散列功能的情况下工作正常。 现在, 我正在尝试为其添加一个重新哈希函数,它允许每次负载因子超过 0.75 时重新哈希它。但它不能正常工作。我需要这方面的帮助..告诉我我做错了什么?
字典和列表结构在这里:
//List of bins
struct list {
char *key;
unsigned long hash;
void *user_data;
struct list *next;
};
//Main hash table Dictionary
struct dict {
struct list **bins;
unsigned int nbins;
unsigned long int count; /* for rehashing - for calculation load factor */
void (*deleter)(void *user_data);
};
这些是我记录的重新散列的步骤。
1. malloc() 一个两倍大的新 bin 数组
newNumberOfBin = D->nbins;
2.将所有列表节点移动到新数组
-Get Stored hash
-Calulate new bin number of list node as
int newBinNo = hash % newNumberOfBin;
-Move node to new bin
3.免费的旧 bin 数组
4.更新 struct dict 成员
-bin will point to new_bins
-nbins will be updated
rehash 函数如下所示
static int dict_rehash(struct dict *D)
{
int idx;
int new_idx;
unsigned int new_nbins;
struct list **new_bins;
struct list *cur;
//This block is just for debugging purpose..its working fine
#if DEBUG
/* print # of items in each bin */
dict_debug_bin_fill(D);
fprintf(stderr,"Rehashing...\n");
/* pause for 3 seconds */
sleep(3);
#endif
new_nbins = D->nbins*2;
new_bins = malloc(new_nbins*sizeof(*D->bins));
for (idx=0; idx<D->nbins; idx++) {
for(cur=D->bins[idx]; cur; cur=cur->next) {
new_idx = cur->hash%new_nbins;
struct list *cur2 = new_bins[new_idx];
while(cur2 != NULL){
cur2=cur2->next;
}
cur2 = cur;
}
}
free(D->bins);
D->bins = new_bins;
D->nbins = new_nbins;
return 0;
}
解决方法
在您的代码中,您遍历新 bin 中的列表,然后重新分配一个局部变量,它不会对您的实际列表执行任何操作。当您删除旧 bin 并将新 bin 列表附加到哈希表时,节点仍位于旧 bin 中并且无法访问。
相反,对于每个旧 bin,当 bin 的列表不为空时,提取其头部。找到新的 bin 并将提取的节点插入到它的头部。 (垃圾箱中物品的顺序在这里无关紧要。)
提取第一个节点很容易:保存节点并将头部设置为下一个节点。在列表的头部插入也很容易:将节点的链接设置为头部,然后将头部设置为插入的节点。
所以:
static int dict_rehash(struct dict *D)
{
unsigned int new_nbins = D->nbins * 2;
struct list **new_bins = malloc(new_nbins * sizeof(*D->bins));
for (idx = 0; idx < D->nbins; idx++) {
while (D->bins[idx]) {
struct list *cur = D->bins[idx];
int new_idx = cur->hash % new_nbins;
// remove node from old list;
D->bins[idx] = cur->next;
// insert node at fromt of new list
cur->next = new_bins[new_idx];
new_bins[new_idx] = cur;
}
}
free(D->bins);
D->bins = new_bins;
D->nbins = new_nbins;
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。