【问题标题】:Deleting elements in linked list删除链表中的元素
【发布时间】:2018-04-19 15:18:19
【问题描述】:

这出现在关于算法和数据结构的旧考试之一中。这看起来很简单,但我需要一些帮助来理解它的工作原理。

目标是仅使用指向头的指针从单链表中删除某些原子。

原子的结构是:

struct at {
 int element;
 struct at *next;
};
typedef struct at atom;

解决办法是:

void delete(atom **head)
{
  while((*head)){
    if((*head)->element%2){ /*just a condition for deleting*/
      (*head)=(*head)->next; /*deleting the atom*/
    } else {
       head= &(*head)->next; 
    }
   }
 }

我的理解是,在这个函数中,“*head”是实际的头部(指向第一个原子的指针),而“head”是指向实际头部的指针。显然,因为我实际上会更改列表的头部和内容,所以我需要传递一个指向头部的指针。

我只是不明白 head= &(*head)->next 似乎是如何工作的。我试过把它写在纸上,但仍然无法理解。它如何不改变任何东西而只是跳转到下一个原子?

【问题讨论】:

  • head 是指向指针的指针。就像任何其他指针一样,它保存其底层类型的实体的地址,在本例中是指向atom 的指针。像所有指针一样(尽管有void*),*p = ... 取消引用指针并分配给它指向的内容。而p = ... 更改了指针中保存的地址。相关的,除非在其他地方处理内存管理,否则这个“解决方案”会放弃与给定链表断开连接的节点;即,这是内存泄漏的秘诀。

标签: c singly-linked-list


【解决方案1】:

正如你所说,*head 是实际的头(指向第一个原子的指针),head 是指向实际头的指针。在语句 head= &(*head)->next; 我们正在用实际头节点旁边的节点地址更新head(其中包含实际头的地址)。

现在head 是一个指针,它存储头的地址到下一个节点而不是头节点,即下一个原子。

考虑一个列表 1->2->3->4->5

在这种情况下,最初 head 包含地址节点 1,而 *head 是节点 1 本身。 现在当我们说head= &(*head)->next; 意味着head 将存储节点2 的地址。如果我们这样做*head 它返回节点2。

【讨论】:

    猜你喜欢
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多