如何删除双向链表中与特定值匹配的所有项目
How to delete all items in a doubly linked list that match a certain value?
我有一个作业,我必须编写一个函数,该函数可以删除双链表的任何部分,该双向链表有一个具有预定输入的值。我为此工作了相当长一段时间,我找不到我编写的代码的任何其他错误。作业内容如下:
编写一个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
并且需要删除所有 3,它得到的结果是
1 <-> 2 <-> 4
这是正确的。它适用于需要删除头部项目的其他示例,以及需要删除尾部的示例。它与每个所需的功能一起工作。此外。。。
2 <-> 2 <-> 2 <-> 2 <-> 65 <-> 83
需要删除 2 的地方。它只得到一个结果
2<-> 65 <-> 83
因此,由于某种原因,还剩下额外的 2 个。有什么猜测吗?我已经为这个问题提供了我提供的一切。我认为问题可能出在我的部分删除双向链表中的中间项目,但我完全迷失了。非常感谢!
这看起来很可疑(添加一些空格):
node* node1 = tmp;
node1->prev->next = node1->next;
node1->next->prev = node1->prev;
delete tmp;
tmp = node1;
node1
只是tmp
的别名。它实际上没有任何其他目的。然后你delete
tmp
并将其分配给node1
- 这正是你刚刚删除的内容!
您可能想执行以下操作:
tmp->prev->next = tmp->next;
tmp->next->prev = tmp->prev;
node* prev = tmp->prev;
delete tmp;
tmp = prev;
当初始头节点与值匹配时,会出现此问题。
在这种情况下,您将下一个节点设置为新头并摆脱旧头,然后将 tmp 设置为新头,
if(tmp==head){
head=head->next;
head->prev=NULL;
delete tmp;
tmp=head;
}
然后当你退出你设置的 if 语句时
tmp = tmp-> next
因此,在 if 块中,您将当前节点设置为下一个节点,然后删除曾经是当前节点的内容,然后当您退出 if 语句时,您将再次向下移动到下一个节点,有效地完全跳过新的头节点。
我补充了巴里的回答:
node *temp=tmp;
temp->prev->next=NULL;
delete tmp;
tmp=temp;
这将为当前节点tmp
设置别名temp
,然后将上一个节点的next
指针设置为 NULL,删除当前节点并将 tmp 指针设置为 temp
,但这只是刚刚删除的节点的别名。您可能希望node *temp=tmp->prev;
将 tmp 设置为新的最后一个元素。
可能导致您的错误的是,关于您与价值的比较,您调用
tmp=tmp->next;
最后,转到下一个节点。您应该将其包装在 else 块中,以便仅在您的值不匹配时才执行。
定义双向链表时,通常会定义一个单独的结构,其中包含两个指针:一个指向列表头部的指针,另一个指向列表尾部的指针。例如
struct list
{
node *head = nullptr;
node *tail = nullptr;
//...
};
同样在结构内部声明成员函数处理列表。
但是,如果使用您的方法,那么删除所有值等于给定值的节点的函数可以看起来像本演示程序中显示的那样
#include <iostream>
struct node
{
int value;
node *next;
node *prev;
};
void display( node *head )
{
for ( ; head; head = head->next )
{
std::cout << head->value << ' ';
}
std::cout << std::endl;
}
node * AppendNode( node *head, int value )
{
node *tmp = new node { value, nullptr, nullptr };
if ( !head )
{
head = tmp;
}
else
{
node *prev = head;
while ( prev->next ) prev = prev->next;
tmp->prev = prev;
prev->next = tmp;
}
return head;
}
node * DeleteNode( node *head, int value )
{
for ( node *current = head; current; )
{
if ( current->value == value )
{
node *tmp = current;
if ( current->next )
{
current->next->prev = current->prev;
}
if ( current->prev )
{
current->prev->next = current->next;
current = current->next;
}
else
{
head = current->next;
current = head;
}
delete tmp;
}
else
{
current = current->next;
}
}
return head;
}
int main()
{
node *head = nullptr;
for ( int x : { 2, 2, 2, 2, 65, 83 } ) head = AppendNode( head, x );
display( head );
head = DeleteNode( head, 2 );
display( head );
head = DeleteNode( head, 83 );
display( head );
head = DeleteNode( head, 65 );
display( head );
}
它的输出是
2 2 2 2 65 83
65 83
65
- 从链接列表c++中删除一个项目
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 如何自动获取我的项目的路径并删除一些文件
- 如何从 CLion 的运行窗口中删除程序项目路径
- 类(可能是代理)的命名,允许在不修改基础容器的情况下对项目进行排序和删除
- C++ 从链表中删除项目时出现问题
- 仅从无序集合中删除一个项目
- Visual studio安装项目删除以前的版本
- 如何使用擦除和迭代器来删除二维向量中的项目
- 从 std::vector 中删除项目时"Iterator not incrementable"
- C++ priority_queue与自定义比较器并删除任何项目
- 从 QTreeView 中删除项目时取消选择所有行
- 擦除删除成语的性能增益从何而来
- 如果为空,则从 QListWidget 中删除可编辑项目
- C++对象池,它以智能指针的形式提供项目,这些项目在删除时返回到池中
- qt QAbstractItemModel 拖放用于移动项目执行删除/插入
- Visual Studio在我从项目中删除的文件上抛出错误
- 为什么在我的项目中删除使用命名空间std会导致错误
- 编译c++项目时删除函数名
- vc++ 2010 Express |编译器从我的项目中删除了一些代码