单链表
单链表中的每个结点不仅包含值,还包含链接到下一个结点的引用字段。通过这种方式,单链表将所有结点按顺序组织起来。、
下面是一个单链表的例子:

蓝色箭头显示单个链接列表中的结点是如何组合在一起的。
结点定义:
struct SinglyListNode{ int val; SinglyListNode *next; SinglyListNode(int x):val(x),next(NULL){} }
在大多数情况下,我们将使用头结点(第一个结点)来表示整个列表。
与数组不同,我们无法在常量时间内访问单链表中的随机元素。 如果我们想要获得第 i 个元素,我们必须从头结点逐个遍历。 我们按索引来访问元素平均要花费 O(N) 时间,其中 N 是链表的长度。
例如,在上面的示例中,头结点是 23。访问第 3 个结点的唯一方法是使用头结点中的“next”字段到达第 2 个结点(结点 6); 然后使用结点 6 的“next”字段,我们能够访问第 3 个结点。
如果我们想在给定的结点 prev 之后添加新值,我们应该:
- 使用给定值初始化新结点
cur;![]()
- 将
cur的“next”字段链接到 prev 的下一个结点next;![]()
- 将
prev中的“next”字段链接到cur。![]()
与数组不同,我们不需要将所有元素移动到插入元素之后。因此,您可以在 O(1) 时间复杂度中将新结点插入到链表中,这非常高效。
在开头添加结点
众所周知,我们使用头结点来代表整个列表。
因此,在列表开头添加新节点时更新头结点 head 至关重要。
- 初始化一个新结点
cur; - 将新结点链接到我们的原始头结点
head。 - 将
cur指定为head。
例如,让我们在列表的开头添加一个新结点 9。
- 我们初始化一个新结点 9 并将其链接到当前头结点 23。
![]()
- 指定结点 9 为新的头结点。
删除操作 - 单链表
如果我们想从单链表中删除现有结点
cur,可以分两步完成:- 找到 cur 的上一个结点
prev及其下一个结点next;![]()
- 接下来链接
prev到 cur 的下一个节点next。![]()
在我们的第一步中,我们需要找出
prev和next。使用cur的参考字段很容易找出next,但是,我们必须从头结点遍历链表,以找出prev,它的平均时间是O(N),其中 N 是链表的长度。因此,删除结点的时间复杂度将是O(N)。空间复杂度为
O(1),因为我们只需要常量空间来存储指针。删除第一个结点
如果我们想删除第一个结点,策略会有所不同。
正如之前所提到的,我们使用头结点
head来表示链表。我们的头是下面示例中的黑色结点 23。![]()
如果想要删除第一个结点,我们可以简单地
将下一个结点分配给 head。也就是说,删除之后我们的头将会是结点 6。![]()
链表从头结点开始,因此结点 23 不再在我们的链表中。
- 找到 cur 的上一个结点









浙公网安备 33010602011771号