【发布时间】:2016-05-31 08:01:36
【问题描述】:
我有一个任务,我必须编写一个函数,该函数可以删除双向链表的任何部分,其中存在具有预定输入的值。我在这方面工作了很长一段时间,我写的代码没有发现任何其他问题。作业是这样写的:
编写一个 C++ 函数来删除链表中的节点。该函数有两个参数——链表的头部和要删除的值。它应该删除所有包含要删除的值的节点。它应该返回链表的头部。
链表结构:
struct node { int value; node *next; node *prev; };
node *DeleteNode(node *head, int value){
node *tmp=head;
while(tmp!=NULL){
if(tmp->value==value){
if(tmp==head){
head=head->next;
head->prev=NULL;
delete tmp;
tmp=head;
}
else if(tmp->next==NULL){
node *temp=tmp;
temp->prev->next=NULL;
delete tmp;
tmp=temp;
}
else{
node *node1=tmp;
node1->prev->next=node1->next;
node1->next->prev=node1->prev;
delete tmp;
tmp=node1;
}
}
tmp=tmp->next;
}
return head;}
所以,当它运行测试时
1 2 3 4
需要删除所有的3s,得到的结果是
1 2 4
这是正确的。它适用于其他需要删除头部项目的示例,以及需要删除尾部的示例。它适用于所有需要的功能....除此之外...
2 2 2 2 65 83
需要删除2s的地方。它只是得到一个结果
2 65 83
因此,由于某种原因,额外的 2 被留下了。有什么猜测吗?我已经提供了我为这个问题提供的一切。我认为问题可能出在我删除双向链表中的中间项目的部分,但我完全迷失了。非常感谢!
【问题讨论】:
-
我不明白
else if(tmp->next==NULL){中发生的事情temp指向与tmp相同。你delete tmp,所以tmp和temp都指向垃圾,然后你将垃圾指针temp分配回tmp。这将在tmp=tmp->next;蓬勃发展 -
再想一想,我认为你可以像地狱一样作弊,因为你在名单的最后。
tmp->prev->next=NULL; delete tmp; return head; -
所有三个答案都带来了重要且不同的细节。建议将它们全部考虑在内。
-
@tschadius 不要着急。即使您将实施答案中显示的解决方案,您的功能也将包含错误。:) 通常只有我的解决方案是正确的。:)
-
你真的应该使用
std::list,这是一个标准化的双链表实现。然后您可以使用std::remove()和std::list::erase()(即所谓的Erase–remove idiom)来删除所有具有相同值的元素(或者您希望使用std::remove_if()代替的任何条件)。
标签: c++ linked-list nodes doubly-linked-list