C删除列表中的第一个元素

时间:2013-01-18 18:50:57

标签: c list struct

我有一个结构:

struct Node {
    int value;
    struct Node *next;
};

typedef struct Node List;

我已经实现了向列表添加项目,但是当它是给定列表中的第一个元素时,我从列表中删除元素时遇到了问题,我的函数:

void removeItem(List *ptr, int i)
{
    List *current = ptr;
    List *prev = NULL;
while (current != NULL)
{
    if (current->value == i)
    {
                    //it's first element
        if (prev == NULL)
        {
            List *replace = ptr->next;
            free(current);
            ptr = replace;
            current = replace;
        }
        else
        {
            prev->next = current->next;
            free(current);
            current = prev->next;
        }
    }
    else
    {
        prev = current;
        current = current->next;
    }
}
}

当我的清单如下:

  

1,2,3,4,5

使用 removeItem(list,1)之后:

  

0,2,3,4,5

0 不应该在那里。

另一个问题是,当typedef不同时,我也应该实现这些功能:

typedef struct Node *List;

但是后来我得到了大量的“错误的论证类型”/“请求成员'价值'而不是结构或联合”错误。我能找到一些如何处理这个问题的例子吗?

3 个答案:

答案 0 :(得分:2)

您的问题是您传入的变量(list)未被删除代码修改。因此,当您移除Node中的第一个List时,系统会留下Node中不再存在的List的引用。

原因是:

当您致电removeItem(list, 1)时,您传递的值为list。在这种情况下,它是类型为List的数据的地址。在removeItem函数内,该值由ptr变量携带。当您输入该函数时,ptr变量是List的地址,您可以使用它。在ptr = replace行中,您所做的只是更改ptr所持有的值。它不会影响list被调用范围内removeItem的值。

最简单的事情是removeList返回指向结果列表头部的指针。对于大多数呼叫,它将与传入的ptr相同;只有当移除的Node位于List的头部时,结果指针才会不同。

或者,您可以更改removeList,以便它需要指向List的指针,然后您将其称为removeList(&list, 1),这样您就可以修改该值直接在list

答案 1 :(得分:1)

这就像家庭作业问题一样,所以我不想直接回答,但有两条线索:

  • 如果您的目标是在调用removeItem()的函数中更改列表指向的内容,那么removeItem()的第一个参数的类型需要是什么?

    < / LI>
  • 如果我告诉你,在某些实现中,free()一个指针变量将该变量指向的空间清零,以帮助调试,这有助于你理解你得到的输出

当你开始工作时,请随时回答你自己的问题。

答案 2 :(得分:0)

所有答案都很有帮助,这是最后一项功能:

void removeItem(List *ptr, int i)
{
    while ((*ptr) != NULL)
    {
        if ((*ptr)->value == i)
        {
            List tmp = *ptr;
            *ptr = (*ptr)->next;
            free(tmp);
        }
        else
        {
            ptr = &((*ptr)->next);
        }
    }
}

按原样运作:

List ptr = malloc(sizeof(List));

//add items to list:
//1, 1, 2, 3, 4, 4, 5, 5,

removeItem(&ptr, 5);
removeItem(&ptr, 2);
removeItem(&ptr, 1);

//print and clean
//3, 4, 4,