Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我一直在重新整理我在C中使用哈希表实现的字典_C_Dictionary_Hashtable - Fatal编程技术网

我一直在重新整理我在C中使用哈希表实现的字典

我一直在重新整理我在C中使用哈希表实现的字典,c,dictionary,hashtable,C,Dictionary,Hashtable,我已经用c语言实现了这个哈希表字典。它工作正常,无需再灰化功能。 现在, 我正在尝试添加一个重新灰化函数,它允许每次负载系数超过0.75时重新灰化它。但它不能正常工作。在这方面我需要帮助。告诉我我做错了什么 dict和list结构如下所示: //List of bins struct list { char *key; unsigned long hash; void *user_data; struct list *next; }; //Main hash t

我已经用c语言实现了这个哈希表字典。它工作正常,无需再灰化功能。 现在, 我正在尝试添加一个重新灰化函数,它允许每次负载系数超过0.75时重新灰化它。但它不能正常工作。在这方面我需要帮助。告诉我我做错了什么

dict和list结构如下所示:

//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。释放旧垃圾箱阵列

  -Get Stored hash 

  -Calulate new bin number of list node as
4。更新结构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;
}

static int dict_rehash(struct dict*D)
{
int-idx;
int new_idx;
未签名的整数新字母;
结构列表**新容器;
结构列表*cur;
//此块仅用于调试目的1.工作正常
#如果调试
/*打印每个箱子中的物品*/
dict_debug_bin_fill(D);
fprintf(标准“再灰化…\n”);
/*暂停3秒钟*/
睡眠(3);
#恩迪夫
新建\u nbins=D->nbins*2;
新料仓=malloc(新料仓*sizeof(*D->bins));
对于(idx=0;idxnbins;idx++){
用于(cur=D->bin[idx];cur;cur=cur->next){
新建\u idx=cur->哈希%new\u nbins;
结构列表*cur2=new_bins[new_idx];
while(cur2!=NULL){
cur2=cur2->next;
}
cur2=cur;
}
}
免费(D->垃圾箱);
D->bins=新的_bins;
D->nbins=新的nbins;
返回0;
}

我需要帮助,在这个函数中我哪里出错了?

在您的代码中,您遍历新bin中的列表,然后只重新分配一个局部变量,这对您的实际列表没有任何作用。删除旧的存储箱并将新的存储箱列表附加到哈希表时,节点仍在旧的存储箱中,将无法访问

相反,对于每个旧垃圾箱,当垃圾箱的列表不是空的时,提取其头部。找到新的bin并在其头部插入提取的节点。(在这里,箱子中物品的顺序无关紧要。)

提取第一个节点很容易:保存节点并将头部设置为下一个节点。在列表的开头插入也很容易:将节点的链接设置为头,然后将头设置为插入的节点

因此:

static int dict_rehash(struct dict*D)
{
无符号整数new_nbins=D->nbins*2;
结构列表**new_-bin=malloc(new_-bin*sizeof(*D->bin));
对于(idx=0;idxnbins;idx++){
而(D->bins[idx]){
结构列表*cur=D->bin[idx];
int new\u idx=cur->hash%new\u nbins;
//从旧列表中删除节点;
D->bin[idx]=cur->next;
//在新列表的起始处插入节点
cur->next=new_bins[new_idx];
new_bins[new_idx]=cur;
}
}
免费(D->垃圾箱);
D->bins=新的_bins;
D->nbins=新的nbins;
返回0;
}

你说“它工作不正常”,但它怎么“工作不正常”?发生了什么事?会发生什么?你们试过调试你们的代码吗?是的,我试过调试它…在将第一个bin的第一项移动到新的_bin数组之后,程序在第一次重新刷新时自动退出。“刚刚退出”听起来像是崩溃了。在监视变量及其值时,您是否尝试使用实际的调试器逐条检查代码语句?
cur2=cur
只更改局部变量,但它对链接列表没有任何作用。您希望从旧表中删除列表节点,并将其插入重新设置的表中。这意味着要调整列表头和节点的链接。你能告诉我更多关于如何在此透视图中调整列表头和节点的信息吗。。!