数据结构 - 第2章 线性表 - 2.3 线性表的链式式表示

本文详细介绍了线性表的链式存储结构,包括单链表、双链表和循环链表的特点与操作。单链表通过附加指针建立元素间关系,解决了顺序表的空间问题,但查找效率较低。双链表增加了双向指针,提高了插入和删除的灵活性。循环链表则形成了首尾相连的结构,便于某些特定操作。此外,还讨论了静态链表作为一种在不支持指针的环境中实现链式结构的方法。在选择存储结构时,需要综合考虑存储需求、运算类型和运行环境等因素。
摘要由CSDN通过智能技术生成

第2章 线性表

2.3 线性表的链式式表示

2.3.1 单链表的定义

线性表的链式存储又称单链表,它是通过一组任意的存储单元来存储线性表中的数据元素。为了建立数据元素之间的关系,对每个链表结点,除存放元素自身的信息之外,还需要存放一个后继指针

datanext

单链表可以解决顺序表需要大量连续存储单元的缺点,但单链表附加指针域,也存在浪费存储空间的缺点

单链表是非随机存取的存储结构,即不能直接找到表中某个特定的结点,因此查找某个特定的结点时,就需要从表头开始遍历,依次查找

通常用头指针来标识一个单链表,如单链表L,头指针为NULL时表示一个空表,此外,为了操作上的方便,在单链表第一个结点之前附加一个结点,称为头结点。头结点的数据域可以不设任何信息,也可以记录表长等信息。头结点的指针域指向线性表的第一个元素结点

头结点和头指针的区分:不管带不带头结点,头指针都始终指向线性表的第一个结点,而头结点是带头结点的链表中的第一个结点,结点内通常不存储信息

引入头结点的两个优点:

1)第一个数据结点的位置被存放在头结点的指针域中,因此在链表的第一个位置上的操作和在表的其他位置上的操作一致,无需进行特殊处理

2)无论链表是否为空,其头指针都指向头结点的非空指针(空表中头结点的指针域为空),因此空表和非空表的处理也就得到了统一

2.3.2 单链表上基本操作的实现

1.采用头插法建议单链表

即在头结点之后插入新的结点(相应的指针指向要更新),采用头插法建立单链表时,读入数据与链表元素生成顺序是相反的。每个结点插入的时间为O(1),设单链表长为n,则总时间复杂度为O(n)

2.采用尾插法建立单链表

即在尾结点之后插入新的结点(相应的指针指向要更新),为此必须增加一个尾指针r,使其始终指向当前链表的尾结点。因为附设了一个指向尾结点的指针,故时间复杂度和头插法相同,实践中经常采用尾插法

3.按序号查找终点值

在单链表中从第一个结点出发,顺指针next域逐个往下搜索,直到找到第i个结点为止,否则返回最后一个结点指针与NULL,按序号查找操作的时间复杂度为O(n)

4.按值查找表结点

从单链表的第一个结点开始,由前往后依次比较表中个结点数据域的值,若某结点数据域的值等于给定值e,返回该结点指针,否则返回NULL,该操作的时间复杂度为O(n)

5.插入结点操作

先判断第i个位置是否合法,然后再插入结点,该算法的主要时间开销在于查找第i-1个元素,时间复杂度为O(n),若在给定的结点后插入新结点,则时间复杂度仅为O(1)

6.删除结点操作

先判断第i个位置是否合法,然后再删除该结点,该算法的主要时间开销在查找操作上,时间复杂度为O(n)

7.求表长操作

求表长就是计算单链表中的数据结点的个数,需要设置一个计数器变量,每访问一个结点,计数器就得+1,直到访问到空结点为止,算法的时间复杂度为O(n)

2.3.3 双链表

单链表结点中只有一个指向其后继的指针,使得单链表只能从头结点依次顺序的向后遍历。要访问某个结点的前驱结点(插入、删除操作时),只能从头开始遍历,访问后继结点的时间复杂度为O(1),访问前驱结点的时间复杂度为O(n)

为了克单链表的上述缺点,引入了双链表(其实这是一种空间换时间的做法),双链表结点中有两个指针prior和next,分别指向前去结点和后继结点

priorainext

双链表中的按值查找和按位查找操作与单链表的相同,插入和删除操作主要要保证操作过程不断链

1.双链表的插入操作

1)将新结点的next指向下一个结点

2)将下一个结点的prior指向新结点

3)将新结点prior指向上一个结点

4)将上一个结点next指向新结点

其中1)和 2)步必须在 4)步之前

2.双链表的删除操作

1)将上一个结点next指向下一个结点

2)将下一个结点prior指向上一个结点

2.3.4 循环链表

1.循环单链表

它和单链表的最大区别在于,表中最后一个结点的指针不是NULL,而改为指向头结点,从而形成一个环

循环单链表的插入、删除算法与单链表几乎一样,对循环链表不设头指针只设尾指针,操作效率更高

2.循环双链表

头结点的prior指向尾结点,尾结点next指向头结点

2.3.5 静态链表

静态链表借助数来描述线性表的链式存储结构,结点也有数据域data和指针域next,但是这里的指针值是结点的相对地址(数组下标),又称游标。和顺序表一样,静态链表也要预先分配一块连续的内存空间静态链表以next==-1作为结束的标志。静态链表的插入、删除操作与动态链表相同,只需要修改指针、而不需要移动元素

总体来说,单链表使用更加方便,但是在一些不支持指针的高级语言中,这是一种非常巧妙的设计方法

2.3.6 顺序表和链表的比较

存取(读写)方式逻辑结构与物理结构查找、插入和删除空间分配
顺序表顺序存取、随机存取逻辑上相邻的元素物理上也相邻按值查找:顺序表无序时O(n),有序时可以采用折半查找O(log2n);按序号查找:O(1);顺序表的插入、删除操作,平均需要移动半个表长的元素顺序存储为静态时,空间无法更改,动态虽然可以扩充,但是需要移动大量元素导致操作效率降低
链表顺序存取元素逻辑关系由指针链接表示,逻辑上相邻,物理位置不一定相邻按值查找:O(n);按序号查找:O(n);链表的插入和删除操作,只需要修改相关结点的指针即可。由于链表的每个结点都带有指针域,故而存储密度不够大链式结点空间只需在需要时申请分配,操作灵活、高效

实际应用中如何选取存储结构?

1.基于存储的考虑

线性表的规模或长度难以估计时不宜采用,但链表的存储密度小于1

2.基于运算的考虑

若查找访问表中元素的话采用顺序表,若插入删除的话,采用链表

3.基于环境的考虑

顺序表容易实现,任何高级语言都有数组类型,链表操作基于指针,进行频繁插入、删除操作的线性表(即动态性较强)宜选择链式存储

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值