关于链表的第一个和最后一个元素的混淆
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于链表的第一个和最后一个元素的混淆相关的知识,希望对你有一定的参考价值。
我很困惑我们是否将元素添加到链接列表的前面或后面。让我们假设我们有一个链接列表,如: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) { ... }
用于链表的常用术语是head
和tail
。
在非循环列表中,就像您在问题中显示的那样,head
节点将是列表中没有其他节点指向的节点,因此您需要另一个指针,即listHead
指针指向它。由于您通常从listHead
指向的节点开始遍历列表,因此head
节点也可以被视为列表中的first
节点。
在非循环列表中,tail
节点是不指向任何其他节点的节点。它可以被认为是列表中的last
节点。
现在,在循环列表中,如您链接的文本中引用的那个,head
和tail
以及first
和last
的定义可能会稍微复杂一些,因为每个节点都指向另一个节点并且有另一个节点指向它。循环列表的开始和结束通常由列表的排序顺序决定,如果有一个或某些其他遍历条件控制您通过列表的顺序。
一个基本的循环列表可能包含一个listHead
指针,指向您在浏览列表时应该访问的first
节点。
一些更高级的循环列表将更改为使用listTail
指针,指向列表的最后一个节点。这样做是因为使用循环列表,如果你有一个指向head
节点的指针,很容易到达tail
节点,因为tail
节点将指向head
节点。因此,通过提供指向tail
节点的指针,您可以快速访问列表中的last
和first
节点。这是链接文本描述的数据结构类型。
现在,关于插入的问题,这完全取决于您以及您希望如何使用列表。如果列表是无序的,则将新节点作为列表的新head
插入速度要快得多。但是,如果您想要实现先进先出列表,那么您可能希望插入新节点作为列表的新tail
。当然,如果列表中有一个订单,基于每个节点包含的一些数据,那么您希望在列表中找到正确的位置以插入新节点以保留排序。
第一个元素是x
,因为如果你通过跟随next
指针链遍历列表,那么你将会得到第一个元素。
添加到链接列表时,可以在第一个元素之前添加,也可以在最后一个元素之后添加。在第一个元素之前添加更有效,因为您不必遵循整个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
,
以上是关于关于链表的第一个和最后一个元素的混淆的主要内容,如果未能解决你的问题,请参考以下文章