文章目录
- 1. 线性表的定义
- 2. 线性表的抽象数据类型
- 3. 线性表的顺序存储结构
- 4. 线性表的链式存储结构
- 5. 单链表结构和顺序存储结构优缺点
- 6. 静态链表
- 7. 循环链表
- 8. 双向链表
1. 线性表的定义
零个或多个数据元素的有限序列
线性表的定义中强调有限和序列两个方面。
- 有限:事实上,计算机中处理的对象都是有限的,那种无限的数列,只存在于数学的概念中。
- 序列:元素之间是有顺序的,若元素存在多个,则赐一个元素无前驱,最后一个元素无后继,其它每个元素都有且只有一个前驱和后继。
2. 线性表的抽象数据类型
3. 线性表的顺序存储结构
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。
线性表顺序存储结构的优缺点:
- 优点:
- 无须为表示表中元素之间的逻辑关系而增加额外的存储空间
- 可以快速地存取表中任一位置的元素,时间复杂度为O(1)
- 缺点:
- 插入和删除操作需要移动大量元素,时间复杂度为O(n)
- 当线性表长度变化较大时,难以确定存储空间的容量
- 造成存储空间的“碎片”
4. 线性表的链式存储结构
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。这就意味着这些数据元素可以存在内存未被占用的任意位置。
头指针与头结点的异同:
-
头指针:
- 头指针是指链表指向物理第一个结点的指针,若链表有头结点,则是指向头结点的指针(上图可能存在错误,0900不是头指针,头指针指向头结点)
- 头指针具有标识作用,所以常用头指针冠以链表的名字
- 无论链表是否为空,头指针均不为空。头指针是链表的必要元素(这里说的头指针不能为空,意思是说头指针一定要存在,而不是说头指针的值不能为NULL。举个例子,当链表为空时,如果有头结点,则头指针指向头结点。如果没有头结点,则头指针为NULL)
-
头结点:
- 头结点是为了操作的统一和方便而设立的,放在逻辑第一个结点之前,其数据域一般无意义(也可存放链表的长度)
- 有了头结点,对在逻辑第一个结点前插入结点和删除逻辑第一个结点的操作与其它结点的操作就统一了
- 头结点不一定是链表的必须要素
5. 单链表结构和顺序存储结构优缺点
存储分配方式:
- 顺序存储结构用一段连续的存储单元依次存储线性表的数据元素
- 单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素
时间性能:
- 查找方面
- 顺序存储结构时间复杂度为O(1)
- 单链表结构时间复杂度为O(n)
- 插入和删除
- 顺序存储结构时间复杂度为O(n)
- 单链表在找出某位置的指针后,插入和删除时间复杂度为O(1)
空间性能:
- 顺序存储结构需要预分配存储空间,分大了浪费,分小了容易发生上溢
- 单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制
6. 静态链表
用数组描述的链表叫做静态链表
静态链表的优点:
- 在插入和删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点
静态链表的缺点:
- 没有解决连续存储分配带来的表长难以确定的问题
- 失去了顺序存储结构随机存取的特性
7. 循环链表
将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表
举例子:上图假设是某人出差的常规路线。有一次,他是先到南京开会,接下来要对以上的城市走一遍。此时有人对他说:你得从上海开始,因为上海是第一站。他一定会觉得这个人是个神经病。因为根本没有必要回上海,可以从南京开始,下一站蚌埠,直到北京,之后再考虑走完上海以及苏南的几个城市。
为什么要使用循环链表:
- 对于单链表,由于每个结点只存储了向后的指针,到了尾标志就停止了向后链的操作,这样,当中某一结点就无法找打它的前驱结点
- 循环链表解决了一个很麻烦的问题,即如何从当中一个结点出发,访问到链表的全部结点
8. 双向链表
双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱
举例子:假设此人先到北京开会,接下来要对以上的城市走一遍。此时有人对他说:你得从上海开始,因为上海是第一站。他一定会觉得这个人是个神经病。因为根本没有必要回上海,直接从北京一路回去到上海就完事了。