【发布时间】:2018-06-04 07:17:01
【问题描述】:
我花了几个小时编写了一个函数——给定一个单向链表,它将删除给定元素的所有出现。这是我设法编写的函数:
void remove_by_value(struct Node **head, int value) {
while( *head!=NULL && (*head)->value == value ) {
struct Node *tmp = *head;
if((*head)->next != NULL)
*head = (*head)->next;
else
*head = NULL;
free(tmp);
}
struct Node *iterator = *head;
while(iterator->next != NULL) {
if(iterator->next->value == value) {
struct Node *tmp = iterator;
iterator = iterator->next;
free(tmp);
continue;
}
iterator = iterator->next;
}
}
在我的示例中,我使用了一个如下所示的简单列表:2->1->1 以及运行remove_by_value(&head, 1) 后程序的输出:
0
1242177584
Segmentation fault (core dumped)
这与预期的效果相去甚远。问题是我不明白我的错误在哪里。这是我想应用的算法:
- 检查此列表的头部是否具有所需的值。如果是这样,将头部向右移动并删除第一个节点。重复此操作,直到新 head 的值与此函数的参数不同
- 检查下一个节点的值是否等于所需值。如果是,则删除该节点并将当前节点与已删除节点之后的节点链接。
我知道我的算法并不完美——例如它不能处理节点不指向任何东西的情况。但问题的核心是我不明白我的程序为什么会这样。你能给我一些建议吗?有没有更好的方法来编写这个算法?
编辑:
我认为这可能很重要,因此我决定包含我的打印功能,因为根据我之前的功能,它可能会导致一些潜在的内存泄漏:
void print(struct Node *head) {
while(head != NULL) {
printf("%d \n", head->value);
head = head->next;
}
}
【问题讨论】:
-
我相信您应该手动检查您在问题陈述中给出的示例的代码 (
2->1->1)。您的代码仅在您的第一个while循环的第一个条件检查中失败(TRUE && FALSE),即它根本没有进入您的第一个while循环。在第二个while循环中,你释放了tmp,它当前指向2 -
我只是好奇。为什么你的程序会有输出? 0 和 1242177584 是什么意思?
-
@leyanpan 我运行了函数,然后运行了我包含的打印函数。
-
你还应该花几个小时调试你的代码,单步执行,检查值等等。这就是开发软件的方式:(
-
@Aemilius 你应该发布一个minimal reproducible example 并告诉我们你的程序的输入是什么(如果有的话)。
标签: c list data-structures linked-list singly-linked-list