如何在C ++中创建一个函数来从链表中删除与搜索键匹配的节点(节点可以是第一个节点以外的任何节点)

How to make a function in C++ to delete a node from the linked list (node can be any except the first node) which matches the searched key

我有一个名为 DeleteData 的函数,我用它来从我的链表中删除任何节点。

void DeleteData(Node *node, int key)
{
   Node temp;
   //If key is in the first node itself
   if (node != NULL && node->read_data() == key)
   {
      temp = *node->next;
      node->next = NULL;
      delete node;
      cout << "New List";
      // It's just a function that reads all data from the linked list given the head reference.
      ListTraverse(&temp);
      return;
   }
   //If key is not in first node
else if (node->read_data() != key)
{
    while (node != NULL && node->read_data() != key)
    {
        // Function to loop thorugh all the nodes
    }
    if (node->read_data() == key)
    {
        //Steps to do, If node is found
    }
}
else
{
    cout<<"Invalid Search key";
}

}

DeleteData 旨在采用两个参数,1。第一个节点的引用2。一把钥匙。我需要删除具有匹配键作为其值的节点。我已经成功地完成了第一部分,即当密钥仅在第一个节点中时,但我无法设计它,以便如果在第一个节点中找不到密钥,它应该继续搜索剩余的节点。

Node is a C++ class having this definition

class Node
{
private:
  int data;

public:
  Node *next;
  void push_data(int x)
  {
      data = x;
  }
  int read_data()
  {
     return data;
  }
};

首先,指定头节点的参数应具有引用类型。

函数可以通过以下方式声明和定义

bool DeleteData( Node * &head, int key )
{
    Node **current = &head;

    while ( *current && ( *current )->read_data() != key )
    {
        current = &( *current )->next; 
    }

    bool success = *current != nullptr;

    if ( success )
    {
        Node *tmp = *current;
        *current = ( *current )->next;
        delete tmp;
    }

    return success;
}

首先,应用单一职责原则:

将搜索要删除的节点与删除它分开。

将工作与决定如何处理结果分开。

这样,任何错误都很难隐藏在混乱中,并且很容易修复。

Node*& findNode(Node*& root, int key) {
    auto p = &root;
    while (*p && (*p)->data != key)
        p = &(*p)->next;
    return *p;
}
void deleteNode(Node*& node) {
    if (node)
        delete std::exchange(node, node->next);
}
bool deleteNode(Node*& root, int key) {
    auto& node = findNode(root, key);
    if (!node) return false;
    deleteNode(node);
    return true;
}