Struct - 删除其中一个元素

时间:2014-04-22 20:21:46

标签: c struct

我们说我有以下结构:

struct object {
    char *name;
    struct object *next;
};

使用它我可以轻松地创建一个表,如K& R C书中所述。并删除所有对象:

object *object_destroy(object *obj)
{
    if (obj != NULL) {
        object_destroy(obj->next);
        free(obj->name);
        free(obj);
        obj = NULL;
    }
}

但我想要的是删除表格中一个的对象,保存所有其他。我真的不知道如何实现它,因为只有free()该对象才能胜任:之后的对象将永久丢失。我也不能obj_to_remove = obj_to_remove->接下来,因为在那之后我将失去那个对象之前的所有对象。

那你能指出我错过的东西吗?感谢。

3 个答案:

答案 0 :(得分:2)

您实际上是在尝试从单链表中删除单个node(而不是双向链表或圆形列表,也称为环形缓冲区) )。

有关单链表概念的更多信息,请参阅以下参考资料。简而言之,你:

  1. 从列表中的第一个节点(head节点)开始。
  2. 一次循环列表一个节点,保留指向先前访问的节点的指针,直到找到要删除的节点。
  3. 将列表中的上一个节点指向当前/找到节点之前的节点 3.1。如果之后没有节点(我们在列表的末尾),则设置为NULL 3.2。如果头/第一个节点是找到的节点,请将head节点设置为列表中的第二个节点。
  4. 如果找到节点,则删除节点内的元素。
  5. 删除当前节点本身。
  6. 第二个参考对您非常有帮助,因为它包括从头开始构建列表,将项添加到列表末尾(追加),在列表中的任意点插入项,删除单个项以及清除列出整个清单。

    <强>参考


    1. 从链接列表中删除,已访问2014-04-22,<https://www.cs.bu.edu/teaching/c/linked-list/delete/>
    2. 单链表 - 插入,删除,添加,统计源代码,已访问2014-04-22,<http://www.cprogramming.com/snippets/source-code/singly-linked-list-insert-remove-add-count>

答案 1 :(得分:-1)

您具有以下1-> 2-> 3-> 4-> 5并且您想要移除元素3.最终结果将是1-> 2-> 4-> 5。

要执行此操作,您只需执行以下步骤:

1-如果元素位于列表的中间:

  • 遍历表格,为每个元素保存前一个元素和元素本身。

  • 当元素等于你要删除的元素时,你有cur_el = 3和prev_el = 2.(cur_el和prev_el是指向元素3和2的指针)

  • 现在只需制作prev_el-&gt; next = cur_el-&gt; next(不要忘记保留指向prev_el的指针。

  • 最后释放cur_el。

2-如果元素是列表中的第一个(假设您要删除1): - 将第一个列表元素设置为cur_el-&gt; next(此处cur_el指向1,列表中的第一个元素)

  • 释放cur_el

3-如果元素位于列表的末尾(在本例中为5): - 转到最后一个元素,获取倒数第二个元素(让我们调用指向prev_el的指针)

  • 设置prev_el-&gt; next = null

  • 免费cur_el

另外,请注意从列表中删除元素的复杂度为O(n),其中n是列表元素的数量。 如果您只是从开头或结尾插入和删除,则可以到达O(1)。

答案 2 :(得分:-2)

在这个问题中,记忆结构被称为“表格”。或许最好将其称为“链接列表”。

int object_destroy(
      object **head, /* The head of the linked-list is required in order to maintain proper list nodes linkage. */
      object  *obj
      )
   {
   int rCode=0;

   /* Unlink the node to be destroyed. */
   if(*head == obj)  /* Is the obj to destroy the head list node? */
      *head = obj->next;
   else 
      {
      object *temp = *head;

      /* Find the parent list node (to the one that will be destroyed). */
      while(temp)
         {
         if(temp->next == obj)
            break;

         temp=temp->next;
         }          

      /* Not found? */
      if(NULL == temp)
         {
         rCode=ENOENT;
         fprintf(stderr, "obj node not found in list\n");
         goto CLEANUP;
         }

      /* Unlink the node, and patch the list so that remaining nodes are not lost. */
      temp->next = temp->next->next;
      }

   /* Free the node to be destroyed. */
   if(obj->name)
      free(obj->name);

   free(obj);

CLEANUP:

   return(rCode);
   }