数据结构之链表


链表是线性表的一种链式存储,即用指针将存储线性表中数据元素的那些单元依次串联在一起。

一、单链表

链表是一系列的存储数据元素的单元通过指针串接起来形成的,因此每个单元至少有两个域,一个域用于数据元素的存储,另一个域是指向其他单元的指针。这里具有一个数据域和多个指针域的存储单元通常称为结点(node)
单链表结点结构

  1. 在 Java 中没有显式的指针类型,然而实际上对象的访问就是使用指针来实现的,即在Java 中是使用对象的引用来替代指针的。因此在使用 Java 实现该结点结构时,一个结点本身就是一个对象。结点的数据域 data 可以使用一个 Object 类型的对象来实现,用于存储任何类型的数据元素,并通过对象的引用指向该元素;而指针域 next 可以通过节点对象的引用来实现。由于数据域存储的也是对象引用,因此数据实际上和图 3-2 中一样,是通过指向数据的物理存储地址来完成存储的。
  2. 链表的第一个结点和最后一个结点,分别称为链表的首结点和尾结点。尾结点的特征是其 next 引用为空(null)。链表中每个结点的 next 引用都相当于一个指针,指向另一个结点,借助这些 next 引用,我们可以从链表的首结点移动到尾结点。如此定义的结点称为单链表(single linked list)
  3. 单链表结构
  4. 在单链表中查找操作只能从前到后,因而运行时间与在数组中的查找操作一样,在平均情况下需要比较大约一般的数据元素,即 T(n) ≈ n/2。
  5. 单链表的三种插入:(时间为是Θ(1))
    表头、中间、表尾

二、双向链表

由于单链表只能通过一个结点的引用访问后续结点,而无法直接访问其前驱结点。在单链表结点结构中新增加一个域,该域用于指向结点的直接前驱结点。扩展后的结点结构是构成双向链表的结点结构,如下图:
双向链表结点结构

  1. 双向链表结构:
    双向链表结构
    2.在双向链表中查找操作可以从链表的首结点开始,也可以从尾结点开始,但是需要的时间和在单链表中一样,在平均情况下需要比较大约一般的数据元素,即 T(n) ≈ n/2
  2. 插入与删除:
    插入删除结点
  3. 在使用单链表实现线性表的时候,为了使程序更加简洁,我们通常在单链表的最前面添加一个哑元结点,也称为头结点在头结点中不存储任何实质的数据对象,其 next 域指向线性表中 0 号元素所在的结点,头结点的引入可以使线性表运算中的一些边界条件更容易处理。比如对于任何基于序号的插入、删除,以及任何基于数据元素所在结点的前面或后面的插入、删除,在带头结点的单链表中均可转化为在某个特定结点之后完成结点的插入、删除,而不用考虑插入、删除是在链表的首部、中间、还是尾部等不同情况。
    在这里插入图片描述
    头节点与头指针的区别:
  • 头结点:1.头节点是为了操作统一和方便设立的,放在第一元素的结点之前,其数据域一般无意义;2.头结点不一定是链表必须元素
  • 头指针:1.是指向链表的第一个结点的指针,若链表有头结点,则是指向头结点的指针;2.头指针有标识作用,常用头指针冠以链表的名字;3.无论链表是否为空,头指针均不为空,头指针是链表必要元素。

三、数组与链式存储的线性表对比

1、基于时间比较

1、查找

基于序号的查找:

  • 数组有随机存取的特性,在线性表的顺序存储实现中可以在**Θ(1)**的时间内完成;
  • 在链式存储中由于需要从头结点开始顺着链表才能取得,无法在常数时间内完成,因此顺序存储优于链式存储;

基于元素查找:

  • 线性表的顺序存储与链式存储都需要从线性表中序号为 0 的元素开始依次查找,因此两种实现的性能相同;

综上所述,如果在线性表的使用中主要操作是查找,那么应当选用顺序存储实现的线性表

2、插入与删除

基于数据元素的插入、删除操作:

  • 数组:需要采用顺序查找定位相应数据元素,然后才能插入、删除,并且在插入、删除过程又要移动大量元素;
  • 链表:只需要在定位数据元素的基础上,简单的修改几个指针即可完成;
  • 链式存储优于顺序存储

基于序号的插入、删除操作:

  • 数组:在顺序存储中平均需要移动一半元素;
  • 链表:不能直接定位,平均需要比较一半元素才能定位;
  • 顺序存储与链式存储性能相当

综上所述,如果在线性表的使用中主要操作是插入、删除操作,那么选用链式存储的线性表为佳

2、基于空间比较

  • 线性表的顺序存储:存储空间是预先静态分配的,虽然在实现的过程中可以动态扩展数组空间,但是如果线性表的长度变化范围较大,空间在使用过程中由于会存在大量空闲空间,使得存储空间的利用率不高
  • 线性表的链式存储:其结点空间是动态分配的,不会存在存储空间没有完全利用的情况。
  • 当线性表长度变化较大时,宜采用链式存储结构
  • 当线性表数据元素结构简单,长度变化不大时可以考虑采用顺序存储结构

四、例题

1、简单例题

例题一——面试题06:从头到尾打印链表
例题二——234:回文链表
例题三——83:删除排序链表中的重复元素

2、中等例题

例题一——82:删除排序链表的重复元素II
例题二——1367:二叉树中的列表
例题三——817:链表组件

3、困难例题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值