1

我完成了插入,在循环链表中搜索,但为了删除,我得到了编译器错误......

以下是我的节点结构。

 struct node
 {
     int               p_data;
     struct node*   p_next;

     node(node* head, int data)
     {
           p_next = head;
           p_data = data;
     }

     explicit node(int data)
      {
           p_next = nullptr;
           p_data = data;
      }
 };




 node* remove_circular(node* head, node* target)
 {
      if (head == target->p_next)
      {
           delete head;
           return nullptr;
      }

      auto next_pointer = target->p_next;
      target->p_data = next_pointer->p_data;
      target->p_next = next_pointer->p_next;

      delete target->p_next;
      return target;
 }

在主函数中我调用

 head = remove_circular(head, head);
 head = remove_circular(head, temp);

这是删除 head 元素和 temp 指向的另一个元素。但我收到错误

有人知道从循环列表中删除一个元素吗?

我将其更改为删除目标-> p_next;但现在它会删除列表中的所有内容。任何想法???

4

3 回答 3

4

这是循环链表的工作原理:


链表示例


每个节点都指向行中的下一个节点,列表的尾部指向头节点。这就是从 acircular linked list到 a的区别regular linked list(在上面的例子中,它会使37指向一个 terminator null)。

如果您的列表只有一个对象,那么它应该如下所示:


唯一节点情况


因此,正如您所看到的,没有指向null任何地方的对象,但是它发生在您的代码中,带有您的explicit构造函数(如果我编写它将运行node n = node(12))。

我建议您查看此链接,以更好地了解您的算法应该是什么样子。

于 2013-08-21T18:55:21.137 回答
2

一旦解决了编译器错误,您仍然会遇到算法问题。我建议你在纸上画一个循环列表,并考虑删除元素所需的步骤。考虑所有情况,例如:空列表、1 项列表、不在列表中的元素等。

于 2013-08-21T18:27:57.517 回答
1

你需要考虑几件事情。

1.) 空列表的情况

  if(head == nullptr){//Empty list case
      return nullptr;
  }

2.) 要删除的目标是头节点,这是列表中唯一的节点。

  if (head == target && target->p_next == head){
       create a temp node with the data value of target
       target = nullptr;//Since nothing points to target now it is for all intents and purposes deleted from the list but the data is still there so you can do something with it. I assume this is necessary because you return a node *.
       return the temp node
  }

3.) 创建一个遍历整个列表的循环。如果您有一个包含两个项目的列表并且目标是第二个项目,那么您有一些东西只会删除下一个有效的节点。

  auto next_pointer = head->p_next;//could not be target->p_next as this assumed 
  while (next_pointer->p_next != target){//This while loop traverses the list rather than just deleting the next entry.

4.)在你的循环中添加一个检查以查看列表是否已被遍历并且目标是否从未找到。

   if (next_pointer->p_next == head){
      return nullptr;
   }//end IF

5.) 在循环内添加 else 情况,这意味着目标位于列表中的任意位置。既然我给了你剩下的,我就让你去拿这部分。比上面的语句长几行并不难。

于 2013-08-21T19:33:26.570 回答