我在删除单链列表中的元素的函数中遇到问题。需要使用功能ShouldDelete()将该元素有条件地删除。
我没有在论坛中的C ++中找到类似的请求,因此不胜感激。以下代码似乎无法100%地起作用。
void SinglyLinkedList::DeleteObjects(Node *pStartPtr)
{
Node *pPtr = pStartPtr;
Node *temp;
while(pPtr != nullptr)
{
temp = pPtr->next;
if (pPtr->ShouldDelete())
{
delete pPtr;
pPtr = temp;
if(temp != nullptr)
{
pPtr->next = temp->next;
}
}
pPtr = temp;
}
}
有什么想法吗?
谢谢!
答案 0 :(得分:0)
作为一般的C ++建议,我将使用std :: list而不是DIY列表实现,但是由于我是在过去的C时代自己写了很多列表逻辑的,所以我会尝试一下。
您的代码有两个基本问题。
首先,每当从单链列表中删除一个元素时,都应将前一个元素的下一个指针设置为已删除元素的下一个指针。您可以执行以下操作:
Node *previousNode = …;
while(pPtr != nullptr)
{
Node *nextNode = pPtr->next;
if (pPtr->ShouldDelete())
{
delete pPtr;
previousNode->next = nextNode;
}
else
{
previousNode = pPtr;
}
pPtr = nextNode;
}
请注意,nullptr
的for循环内不需要特定的if测试。您应该告诉上一个节点,它现在指向已删除节点的下一个。如果没有下一个,则previous->next
只会指向一个nullptr,表示列表的结尾。
第二个问题是您没有明确的“列表起点”。在上面的示例代码中,很难指出previousNode
是什么。是nullptr
吗?但是,如果我们删除第一个元素怎么办?
您可以在此处轻松地添加逻辑以指示跟踪第一个元素,将previousNode
初始化为nullptr,如果删除了第一个元素,则在这种情况下不要设置previousNode->next' and keep previousNode equal to
nullptr`,但是来电者呢?调用者如何知道第一个元素已被删除,并且列表现在稍后开始。
我的首选解决方案是拥有一个单独的List
结构/类,并将列表的开头(第一个节点)保留为List
结构/类的成员。不应将startNode传递给函数,而应传递List
实例。
while循环中的代码现在变得更长了,因为您需要使previousNode->next=nextNode
适应于此:
if (previousNode)
previousNode->next = nextNode;
else
list->firstNode = nextNode;
如果您不想引入新的List
结构/类,也可以从函数中返回新的firstNode
作为返回值,如下所示:
if (previousNode)
previousNode->next = nextNode;
else
startNode = nextNode;
…
return startNode;
请注意,只有在调用者(该函数也是维护列表的函数)并且没有其他指向startNode的位置时,第二种方法才有效。
无论如何,如果涉及多线程,您可能想要一个体面的List
类和一种mutex
(理想情况下std::list
用mutex
装饰)。