有条件地删除C ++中单链接列表中的元素

时间:2019-01-22 04:04:44

标签: c++

我在删除单链列表中的元素的函数中遇到问题。需要使用功能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;
    }
}

有什么想法吗?

谢谢!

1 个答案:

答案 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::listmutex装饰)。