重学数据结构之------链表

123 阅读3分钟

数据结构之------链表

一:首先什么是链表?

链表是数据元素的线性集合,它由一组节点组成,每个数据节点指向下一个数据节点,这些节点在一起表示线性序列。在最简单的链表结构下,每个节点由数据和指针(存放指向下一个节点的指针)组成,这种数据结构允许在迭代时有效的从序列中的任何位置插入或删除元素。

二:链表有哪几种类型?

链表主要分为单向链表,双向链表和循环链表。

单向链表:单向链表也就是上诉所说最简单的链表结构,节点内存放数据本身和一个指向下一个节点的指针

image-20250225203442286.png

双向链表:双向链表除了像单向链表外,还包含了指向序列前一个节点的第二个链接字段,两个链接字段可以称位 prev(前节点)和nest(后节点)

image-20250225203733709.png

循环链表:循环链表相对于单向链表则是列表中最后一个节点指向列表中的第一个节点。

image-20250225204319985.png

三:链表用java代码实现

Node节点源码,每个节点都存储包含元素本身和上下两个节点

image-20250225204927385.png

头插法:每次新建一个prev为空的节点,然后将next指向链表的原头节点,除第一次外,每次再新增节点,原来的头节点prev都会指向新节点

image-20250225205511185.png

image-20250225205520017.png

image-20250225212319859.png

尾插法和头插法相反:每次新建一个nest为空,prev存储linklist中last的节点,然后原last的next存储新的尾节点。

image-20250225212403524.png

链表的删除操作unlink:将删除元素的prev中的next存储删除元素的next,将删除元素的prev置空,将删除元素的next中的prev存储删除元素的prev,将删除元素的next置空,最后再将删除元素节点的item数据置空。unlink删除元素不需要遍历,只需要修改前后指针节点,所以时间复杂度是O(1),但是在remove删除中需要for循环遍历查找元素删除,所以这个比对查找元素的时间复杂度是O(n),删除过程是O(1),所以如果删除的这个元素在链表的末尾端,那么删除的过程是比较耗时的。

image-20250225220725287.png

四:什么场景下使用链表更合适?

  1. 频繁的插入和删除操作:在需要频繁进行插入和删除元素的场景中,链表具有明显优势。例如在一个任务调度系统中,任务的添加和移除操作非常频繁。使用链表,在链表的任意位置插入或删除一个节点的时间复杂度平均为 (双向链表在已知节点位置时)或 (单链表找到插入 / 删除位置时),而数组在中间位置插入或删除元素时,需要移动大量后续元素,时间复杂度为 。所以对于这种对插入和删除操作性能要求较高的场景,链表更为合适。
  2. 数据量不确定且需要动态增长或缩减:当数据量事先无法确定,并且可能会动态地增长或缩减时,链表是很好的选择。比如在一个实时日志记录系统中,日志条目数量会随着时间不断增加,且可能在某些情况下需要删除旧的日志条目。链表不需要像数组那样预先分配固定大小的空间,它可以根据实际需要动态地分配和释放内存,不会造成内存的浪费或溢出。