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

时间:2015-02-14 14:24:15

标签: c linked-list

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

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,我就不会有任何问题。 )。 有什么想法可以解决问题吗?

2 个答案:

答案 0 :(得分:0)

你让它变得比它需要的复杂得多。有几种方法可以删除前向链接的,以空值终止的链表中的节点。您可以使用两个指针(前一个和当前指针)来执行此操作,这就是您尝试使用的指针。在您理解实际算法之前停止编码:

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指向列表中的前一个节点,指向当前测试节点,最初为NULL,cur,我们正在测试的当前节点,最初是名单头。

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

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

真的就是这一切。我强烈建议您通过调试器手动执行删除操作,并查看指针在此过程中的地址。调试器不仅仅是为了找到破碎的东西。它们是帮助更好地理解代码如何工作的一个很好的工具(因为你实际上可以实现"看到"它工作)。

祝你好运。

答案 1 :(得分:0)

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