我在C中,需要删除链接列表中多次出现的'key'字符,并返回链表的头部。
只有当'key'不是第一个或最后一个节点'char'时,此功能才能正常工作, 链表。示例...使用键'a'
fails: a->d->a->m->NULL (throws error)
fails: t->a->d->a->NULL (throws error)
passes: d->a->g->n->a->b->NULL (returns d->g->n->b->NULL )
此外,任何带有“钥匙”的东西都会立即重复失败。示例...使用键'a'
fails: d->a->a->a->a->r->n->NULL (returns d->a->a->r->n->NULL)
-----------------------------删除()--------------- ------------------------
node* delete2(char key, node* head)
{
/*IF NULL*/
if(!head)
{
return head;
}
node* prev = NULL;
node* current = head;
/*if first node(head) is to be deleted*/
while (current && current->data == key)
{
prev = current;
current = current->next;
head = current;
free(prev);
}
/*scan list left to right*/
while (current)
{
if (current->data == key)
{
prev->next = current->next;
free(current);
current = prev->next;
}
prev = current;
current = current->next;
}
return head;
}
答案 0 :(得分:2)
它应该是这样的:
node * remove_key(char key, node * head)
{
// remove initial matching elements
while (head && head->data == key)
{
node * tmp = head;
head = head->next;
free(tmp);
}
// remove non-initial matching elements
// loop invariant: "current != NULL && current->data != key"
for (node * current = head; current != NULL; current = current->next)
{
while (current->next != nullptr && current->next->data == key)
{
node * tmp = current->next;
current->next = tmp->next;
free(tmp);
}
}
return head;
}
作为一项有趣的心理练习,想象一下你有一个"交换"功能(就像C ++一样):
node * exchange(node ** obj, node * newval)
{ node * tmp = *obj; *obj = newval; return tmp; }
然后你可以非常简单地编写这段代码:
node * remove_key(char key, node * head)
{
while (head && head->data == key)
free(exchange(&head, head->next));
for (node * current = head; current != NULL; current = current->next)
while (current->next != nullptr && current->next->data == key)
free(exchange(¤t->next, current->next->next));
return head;
}
你甚至可以专注于某种" exchange_with_next":
node * exchange_with_next(node ** n) { return exchange(n, (*n)->next); }
答案 1 :(得分:2)
首先: prev
可能处于未确定状态:您在第一个while
中释放它并在第二个while
中取消引用{ {1}}。如果密钥是第一个字符,这就是函数失败的原因。
第二:如果您的密钥是以下代码的最后一个字符:
prev->next
将失败,因为您取消引用if (current->data == key)
{
prev->next = current->next;
free(current);
current = prev->next;
}
prev = current;
current = current->next;
,但current
为current
。
一步一步:
NULL
if (current->data == key)
{
prev->next = NULL;// current is the last element so current->next == NULL
free(current);
current = prev->next;
}
prev = current;
current = current->next;
if (current->data == key)
{
prev->next = NULL;
free(current);
current = NULL;// because prev->next == NULL
}
prev = current;
current = current->next;
if (current->data == key)
{
prev->next = NULL;
free(current);
current = NULL;
}
prev = NULL;// same again...
current = current->next;