如何解决如果同一索引中的下一个节点不为 NULL,如何删除单向链表链接哈希表的第一个节点?
这是我的功能,如果我用这个功能删除第一个节点,它会删除所有剩余的节点->下一个节点,有人可以帮我吗?
struct node* popCH(char ex[]){
int hash_index = Hash(ex);
node* temp = head[hash_index];
if(temp==NULL){
return NULL;
}
while(temp->next!=NULL && strcmp(temp->next->ex,ex)!=0){
temp=temp->next;
}
if(temp->next==NULL && strcmp(temp->ex,ex)==0){
free(temp);
temp=NULL;
head[hash_index]=NULL;
}
else if(temp->next!=NULL && strcmp(temp->ex,ex)==0){
node* temp2 = temp;
temp = temp->next;
temp = head[hash_index]->next;
free(temp2);
temp2=NULL;
}
}
解决方法
您应该使用指向节点的指针的指针,以便可以删除该节点并且将指向该节点的指针更新为指向下一个节点,而不管该指针是节点中某个指针的头指针。
struct data* popCH(char ex[]){
int hash_index = Hash(ex);
node** temp = &head[hash_index];
if(*temp==NULL){
return NULL;
}
while(*temp!=NULL && strcmp((*temp)->ex,ex)!=0){
temp=&(*temp)->next;
}
if(*temp!=NULL){
node *temp2 = (*temp)->next;
free(*temp);
*temp=temp2;
}
/* return something not to let caller invoke undefined behavior by using the return value */
return NULL;
}
,
一种方法是使用指针到指针,一个很好的答案已经涵盖了这一点。
另一种只是简单地跟踪指向前一个节点的指针,当没有前一个节点时该指针为空:
node *prev = NULL;
while (temp != NULL && strcmp(temp->ex,ex) != 0) {
prev = temp;
temp = temp->next;
}
if (temp != NULL) { // found matching node
// retain data pointer to return before freeing
struct data *data = temp->data;
// two deletion cases: middle of chain or front
if (prev)
prev->next = temp->next;
else
head[hash_index] = temp->next;
free(temp);
return data;
}
// not found
return NULL;
如果我们给链一个代理父级,我们就可以避免出现两次删除的情况。也就是说,我们在链表的前面添加一个虚拟节点,作为第一个节点的前一个节点:
struct data* popCH(const char *ex){
int hash_index = Hash(ex);
// transfer chain into fake extra previous node:
struct node parent = { .next = head[hash_index] };
node *prev = &parent;
node *temp = prev->next;
while (temp != NULL && strcmp(temp->ex,ex) != 0) {
prev = temp;
temp = temp->next;
}
if (temp != NULL) { // found matching node
// retain data pointer to return before freeing
struct data *data = temp->data;
// splice temp out of list by getting
// the previous node to skip it
prev->next = temp->next;
// transfer updated chain back into table:
head[hash_index] = parent.next;
free(temp);
return data;
}
// not found
return NULL;
}
我们从代码中删除了一些测试,但是有一些不必要的内存写入。在返回之前,我们分配给 head[hash_index]
是否真的有必要;只有 parent.next
发生了变化。此外,我们分配了一个完整的 node
局部变量并初始化了它的所有字段,即使我们只访问过`.我们可以通过避免初始化器来避免这样做:
int hash_index = Hash(ex);
// transfer chain into fake extra previous node:
struct node parent;
node *prev = &parent;
node *temp = head[hash_index];
// initialize just parent.next member by assignment;
// other members are left uninitialized.
parent.next = temp;
// rest of code ...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。