C语言 删除双向链表中的节点

rbl8hiat  于 2023-06-28  发布在  其他
关注(0)|答案(1)|浏览(85)

我写了这段代码来从链表中删除一个节点:

void deleteNode(struct node **head, int element)
{
    if (*head == NULL)
        return;

    struct node *temp = *head;
    while (temp != NULL && temp->data != element){
        temp = temp->next;  
    }
    if (temp == NULL) {
        printf("No element in D.L.L");
    }
    else if (temp == *head) {
        *head = temp->next;
        (*head)->prev = NULL;
        free(temp);
    }
    else if (temp->next == NULL)
    {
        temp->prev->next = NULL;
        free(temp);
    }
    else {
        temp->prev->next = temp->next;
        temp->next->prev = temp->prev;
        free(temp);
    }
}

我这样称呼它:

deleteNode(&head, 33);

我不知道为什么deleteNode函数在删除中间节点时显示核心转储错误?此外,它对第一个和最后一个节点也很有效。
我错在哪里?

falq053o

falq053o1#

当列表只有一个元素,并且deleteNode调用将要删除该元素时,就会出现问题。
在这种情况下,这段代码执行:

if (temp == *head) {
    *head = temp->next;
    (*head)->prev = NULL;
    free(temp);
}

但是,当*head更新为NULL时(因为temp->nextNULL),下一次赋值会产生无效的引用。这个(*head)->prev = NULL赋值不应该在列表变为空的时候执行。
因此,修复如下:

if (temp == *head) {
        *head = temp->next;
        if (*head) { // Guard against invalid dereferencing
            (*head)->prev = NULL;
        }
        free(temp);
    }

旁注:当在非空列表中没有找到节点时输出消息,而当列表为空时保持静默,这是不一致的。我不会输出任何东西,而是返回一个布尔值,指示删除是否成功。

相关问题