如何获取链表指针的地址,以便在删除c中的一项后在哈希表中正确设置它?
从哈希表中删除元素时,我需要遍历发生冲突的元素的链接列表。我使用指针操作来实现这一点,我的链表是如何获取链表指针的地址,以便在删除c中的一项后在哈希表中正确设置它?,c,pointers,C,Pointers,从哈希表中删除元素时,我需要遍历发生冲突的元素的链接列表。我使用指针操作来实现这一点,我的链表是bucket\t的形式。我面临的问题是,当我试图保存第一个ht->bucket[I]的位置时,该值会随着其他值的变化而变化,因此在函数结束时,我的头正好位于next的位置,并导致分段错误。我对在c中使用这样的指针还不熟悉,如果我的解释不好,我很抱歉,但我认为代码非常简单,你们可以看到我试图实现的目标: void ht_del(hashtable_t *ht, char *key) { bucket_
bucket\t
的形式。我面临的问题是,当我试图保存第一个ht->bucket[I]
的位置时,该值会随着其他值的变化而变化,因此在函数结束时,我的头正好位于next
的位置,并导致分段错误。我对在c中使用这样的指针还不熟悉,如果我的解释不好,我很抱歉,但我认为代码非常简单,你们可以看到我试图实现的目标:
void ht_del(hashtable_t *ht, char *key) {
bucket_t *last=NULL, *next=NULL, *head=NULL;
unsigned long i;
for(i = 0; i < ht->size; i++){
head = ht->buckets[i];
next = ht->buckets[i];
while(next && next->key && strcmp(next->key,key)!=0){
last = next;
next = next->next;
printf("\nvisiting next\n");
printf("key = %s\n", head->key);
}
if(next && next->key && strcmp(next->key,key)==0){
printf("key found, removing key = %s, val = %s:", next->key, next->val);
free(next->key);
free(next->val);
if(next->next){
last->next = next->next;
printf("Last->next ->key = %s\n", last->next->key);
}
else{
free(next->next);
printf("end of the line\n");
}
free(next);
printf("head key = %s", head->key);
}
}
}
如何获取链接列表指针的地址,以便在删除某个项后在哈希表中正确设置它
要从链接列表中删除节点,请跟踪上一个节点
为什么要用
printf(“key=%s\n”,head->key”)重复打印head
键在while()
循环中的code>?我这样做只是想看看在遍历链表时它是否在变化。嗯,假设while(…&&strcmp(next->key,key)!=0)
第一次失败,因为字符串比较相等<代码>如果(…&&strcmp(下一步->键,键)==0)
将通过,稍后代码将通过如果(下一步->下一步){
。如果这是真的,那么代码会NULL->next=…
,这是一个问题。我没有看到。很可能是其他代码中存在问题。嗯,这一点很好。我对此进行了快速修复,但这并没有停止问题。我面临的问题是,当我上下移动时,它也会移动ht->bucket[I].因此,无论使用不同的变量,我的头都会不断移动,最终会被删除。这是对代码的极大改进,也是哈希而不是for循环的一大优点,谢谢你们。但是,我仍然有同样的问题,因为我仍然在同一个位置出现分段错误,因为ht->bucket[I]被移动,并最终被删除。@LucasTrestka可能发布了足够多的可编译代码,添加到HT,从HT删除,然后是seg错误。我找到了解决方案,您的代码很好,唯一需要做的就是将HT->Bucket[I]=previous->next设置为代码的最后一行。@LucasTrestka我对HT->Bucket[I]有疑问=前一次>下一次>代码>我想我的更新修复了这个问题。如果你还有问题,请告诉我。次要:更好地使用<代码> SigZiTi;<代码> > <代码>未签名的长i; HTT>大小<代码>是素数。
typedef struct hashtable hashtable_t;
typedef struct bucket bucket_t;
struct bucket {
char *key;
void *val;
bucket_t *next;
};
struct hashtable{
unsigned long size;
bucket_t **buckets;
};
for(i = 0; i < ht->size; i++){
bucket_t before_head = { .next = ht->buckets[i] }; // Only next member used.
bucket_t *previous = &before_head;
while (previous->next && strcmp(previous->next->key,key) != 0) {
previous = previous->next;
}
if (previous->next) { // match was found
// delete previous->next and its members allocations
bucket_t *node_after_match = previous->next->next;
free(previous->next->key);
free(previous->next->val);
free(previous->next);
// link previous to node after deletion.
previous->next = node_after_match;
// assign a potential new head of the list
ht->buckets[i] = before_head.next;
break; // exit for loop
}
}
// for(i = 0; i < ht->size; i++){
i = hash(key)%ht->size;
void ht_del(hashtable_t *ht, char *key) {
unsigned long i;
i = hash(key)%ht->size;
bucket_t before_head = { .next = ht->buckets[i]};
bucket_t *previous = &before_head;
while(previous->next && strcmp(previous->next->key,key)!=0) {
previous = previous->next;
}
if(previous->next ) {
bucket_t *next = previous->next->next;
bucket_t *b = previous->next;
free(previous->next->key);
free(previous->next->val);
previous->next = next;
free(b);
ht->buckets[i] = previous->next;
}
}