什么是(单向)链表
当谈论单向链表时,不妨将其类比为一列火车车厢相互连接的情景。你可以随时在这列火车中插入新的车厢,或者移除现有的车厢,而你站在火车头部,需要前进到第N节车厢,这意味着你必须经过1、2、3一直到N-1号车厢,最终到达目标N号车厢。这个火车头就是单向链表的头节点,每一节车厢都是一个节点,节点中保存着下一节车厢的信息。
但为了更形象地描述单向链表,让我们换个方式来看待它。想象一个场景:你手里拿着一封信,这封信上写着:“亲爱的朋友,跟随我的指引,你将找到隐藏的宝藏!”并在信上写下了下一封信的地址,“张三家后花园的草丛里”。这封信就相当于链表的头节点。
你遵循地址,找到了下一封信,它也包含一段话和下一封信的地址。
这样,你不断地跟着地址找到了最后一封信(尾节点),也找到了宝藏。
当然,在数据结构的世界中,没有真正的宝藏,这个描述只是为了帮助你更好地理解单向链表。
理想的单向链表
不同于线性顺序存储的数组,链表不要求数据按线性顺序存储。这意味着我们可以将链表的节点存储在任何地方,每个节点都是一个包含值和下一个节点地址的变量。最后一个节点的地址通常是null,如果是循环链表,最后一个节点应该指向头节点。因此,我们只需要知道一个节点,就可以遍历整个链表。我们可以声明一个指向头节点的指针,以便访问整个链表的每个节点。
下面的图示更形象地展示了这个概念。考虑一个链表:6 -> 9 -> 3 -> 2 -> null。
更抽象的逻辑视图如下:
与数组一样,链表的插入和删除操作的时间复杂度都是O(n)。
不同的是,链表的遍历操作更耗时,而数组则需要频繁移动元素。
不过,链表在内存使用方面更加高效,因为它只使用必要的内存。
单向链表基本操作:插入
我们希望能够在链表的任意位置插入新的节点。
-
插入头部:插入新节点到链表的头部,只需要声明一个新节点,将新节点的下一个节点指向当前头节点,然后更新头指针。
如下图所示:
-
一般插入:如果要在链表的中间或尾部插入节点,首先要遍历到插入位置的前一个节点,然后将新节指向前一个节点的下一个节点,最后前一个节点指向插入的节点。
如下图所示:
单向链表基本操作:删除
删除操作相对简单,如下图所示:
单向链表基本操作:反转
至于链表反转,请查看下图:
改变箭头的指向,并使头节点指地。
结语
希望这篇文章可以帮助你更好的理解单向链表。😊
不可否认,由于本人孤酒小同学的水平有限,可能会有不清楚的地方。
欢迎各位帅哥美女的批评与指正。