C 无法从链表中删除最后一个元素

C 无法从链表中删除最后一个元素,c,linked-list,C,Linked List,我无法从链表中删除最后一个元素,问题是当我删除它时,我唯一拥有的节点是previus节点(在最后一个之前)。这是我的密码: node *remove_node(int d, node *lst){ node *prev; node *temp = lst; if(temp->data == d){ if(temp->next != NULL){ node *sec_temp = temp; tem

我无法从链表中删除最后一个元素,问题是当我删除它时,我唯一拥有的节点是previus节点(在最后一个之前)。这是我的密码:

node *remove_node(int d, node *lst){
    node *prev;
    node *temp = lst;
    if(temp->data == d){
        if(temp->next != NULL){
            node *sec_temp = temp;
            temp = temp->next;
            free(sec_temp);
            return temp;
        }
        else{
            free(temp);
            return NULL;
        }
    }
    while(temp != NULL && temp->data != d){
        prev = temp;
        temp = temp->next;
    }
    if(temp == NULL){return lst;}
    //Here is the problem
    if(temp->next == NULL){
        prev->next = NULL;
        free(temp);
        return prev;
    }
    //end
    else {
        prev->next = temp->next;
        free(temp);
        return prev;
    }
}
int main(){
    node *lst = NULL;
    lst = new_node(1, lst);
    lst = new_node(2, lst);
    lst = new_node(3, lst);
    lst = new_node(4, lst);
    lst = remove_node(1, lst);
    print(lst);// this will print the list, works perfect
    return 0;
}
当我删除1(这是列表中的最后一个元素)时,只打印2,在其他情况下,一切都很完美(如果我删除2、3或4,我没有任何问题)。
你知道问题的起因吗?

你把问题弄得比实际情况复杂得多。有几种方法可以删除前向链接、以null结尾的链接列表中的节点。您可以使用两个指针(前一个指针和当前指针)执行此操作,这似乎是您正在尝试的。在理解实际算法之前停止编码:

node *remove_node(int d, node *lst)
{
    node *prev = NULL, *cur = lst;

    while (cur && cur->data != d)
    {
        prev = cur; 
        cur = cur->next;
    }

    if (cur)
    {
        if (!prev) // head node was the match
            lst = lst->next;
        else
            prev->next = cur->next;
        free(cur);
    }
    return lst;
}
它的工作原理

最初,我们有两个指针,
prev
,它指向列表中的前一个节点,指向当前测试节点,并且最初为空;
cur
,我们正在测试的当前节点,最初为列表头

每次遍历列表一个节点,每次测试是否(a)尚未到达列表末尾(
cur!=NULL
)和(b)找到与目标数据匹配的节点(
cur->data==d
)。我们相应地打破了循环。一旦循环中断,
cur
要么引用要删除的节点,要么为NULL,这意味着我们找不到匹配项

只有当
cur
非空时,
prev
的值才重要,这意味着我们找到了匹配项。如果我们找到了匹配项并且
prev==NULL
我们必须在head节点上,否则
prev
指的是
next
指针需要链接到
cur->next
指针的节点,以拼接列表并在删除之前删除受害者

这就是它的全部。我强烈建议您在调试器中手动执行删除操作,并查看指针在执行过程中的地址。调试器不仅仅是用来查找损坏的东西。它们是一个很好的工具,可以帮助您更好地理解代码是如何工作的(因为您可以真正“看到”它是如何工作的)


祝您好运。

问题是您返回的
prev
指针指向被删除元素之前的元素,但实际上列表的开头仍然是
lst
指针。接下来在
main
方法中,您在打印方法中使用返回的指针,因此只打印最后一个元素。

您不更新下一个指针。你不能简单地释放列表中间的一个节点,因为下一个指针现在指向一个释放的节点。我不明白你的意思,这是我必须删除的节点是最后一个的情况,所以我将列表中的Payvies元素设置为NULL(列表的末尾),然后释放应该删除的节点。(最后一个节点).提示:如果列表中只有一个节点,则此节点也是最后一个。也是第一个。您要求我们相信,
new_node
实际上会在初始插入时将
next
设置为NULL。如果目标节点不在列表中,或者第一个也是唯一一个节点是bein,则您的移除代码将指定给破坏球g deleted,它悬挂一个
temp
指针并调用未定义的行为。1.是的,新的\u节点设置在NULL旁边,正如我所说的,除此之外的所有操作都非常有效。2.如果该节点是第一个(或唯一一个)节点它将进入第一个if条件并被删除,函数将返回。但是我不会检查节点是否真的存在。