我有一个结构:
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;
但是后来我得到了大量的“错误的论证类型”/“请求成员'价值'而不是结构或联合”错误。我能找到一些如何处理这个问题的例子吗?
答案 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()
的第一个参数的类型需要是什么?
如果我告诉你,在某些实现中,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,