【问题标题】:Confusion about the first and the last elements of a linked list关于链表的第一个和最后一个元素的混淆
【发布时间】:2018-03-06 08:01:19
【问题描述】:

我很困惑我们是将元素添加到链表的前面还是后面。假设我们有一个链表,如下所示:x->a->c->v;在这里,x 是第一个还是最后一个元素?其次,如果要加x->a->c->v->h或h->x->a->c->v怎么办?当我遇到以下问题时,这让我很困惑:

考虑实现一个循环单链表数据结构。假设循环链表的指针ptr 指向最后一个节点,其link 字段指向链表的第一个节点。完成下面指定的add(...) 和delete(...) 的算法。您可以编写伪代码或 C 代码。假设链表节点结构声明如下:

typedef struct list_node* list_pointer;
typedef struct list_node {
     int value;
     list_pointer link;
}

list_pointer ptr = NULL;

请注意,如果循环链表为空,则其指针ptr 将设置为NULL。

// Add node at the front of the circular list ptr; ptr points at the last node in the list
void add(list_pointer *ptr, list_pointer node) { ... }

// Delete the front node from the list ptr
list_node delete(list_pointer *ptr) { ... }

【问题讨论】:

  • 为了让事情更简单,想想转发列表
  • @codekaizer 你能详细说明一下吗?

标签: c linked-list


【解决方案1】:

用于链接列表的常用术语是head 和tail。

在非循环列表中,就像您在问题中显示的那样,head 节点将是列表中没有其他节点指向的节点,因此您需要另一个指针,listHead 指针,指向它。由于您一般从listHead 指向的节点开始遍历列表,因此head 节点也可以认为是列表中的first 节点。

在非循环列表中,tail 节点是不指向任何其他节点的节点。它可以被认为是列表中的last 节点。

现在,在一个循环列表中,就像您链接的文本中引用的那样,head 和 tail 以及 first 和 last 的定义可能有点复杂,因为每个节点指向另一个节点并有另一个节点指向它。循环列表的开始和结束位置通常由列表的排序顺序(如果有)或其他一些控制您通过列表的顺序的遍历标准确定。

一个基本的循环列表可以包含一个listHead 指针,该指针指向您在遍历列表时应该访问的first 节点。

一些更高级的循环列表将改为使用listTail 指针,指向列表的最后一个节点。这样做是因为,对于循环列表,如果您有指向 tail 节点的指针,则很容易到达 head 节点,因为 tail 节点将指向 head 节点。因此,通过提供指向tail 节点的指针,您可以快速访问列表中的last 和first 节点。这是您的链接文本所描述的数据结构类型。

现在,关于插入的问题,这完全取决于您以及您希望如何使用该列表。如果列表是无序的,插入一个新节点作为列表的新head 会快得多。但是如果你想实现一个先进先出的列表,那么也许你想插入新节点作为列表的新tail。当然,如果您的列表有顺序,基于每个节点包含的一些数据,那么您希望在列表中找到正确的位置以插入新节点以保持顺序。

【讨论】:

    【解决方案2】:

    第一个元素是x,因为如果您按照next 指针链遍历列表,那将是第一个元素。

    添加到链表时,您可以在第一个元素之前添加,也可以在最后一个元素之后添加。在第一个元素之前添加效率更高,因为您不必遵循整个next 指针链来查找结尾。

    【讨论】:

      【解决方案3】:

      您可以选择自己列表的方向。通常通过命名指向前一个和下一个节点的指针previous 和next。你如何命名它们决定了顺序。如果你有一个双向链表,你的节点有两个指针。

      尽管如此,您总是存储指向第一个和最后一个元素的指针。这样你就可以拥有push_front、pop_front、push_back、pop_back 函数。

      但是,如果你有一个前向列表,(你只将next 指针存储在你的节点中,那么你就不能有一个pop_back,因为你的最后一个节点没有链接到前一个节点,并且你不知道新的最后一个元素会变成什么。

      那么

      • 转发列表可以有:push_front,pop_front,push_back,
      • 后向列表可以有:push_front、push_back、pop_back、
      • 和一个双向链表:push_front,pop_front,push_back,pop_back,

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-09
        • 2021-06-08
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多