一、线性表的定义
零个或多个数据元素的 “有限”“序列” 。
二、线性表的相关概念
- 线性表长度: 线性表元素的个数(n≥0),当n=0时,称为空表;
- 前驱元素: 相对于表内的某元素,位于其位置前面的元素;
- 后驱元素: 相对于表内的某元素,位于其位置后面的元素;
- 直接前驱元素: 相对于表内的某元素,相邻于其位置前面的元素;
- 直接后驱元素: 相对于表内的某元素,相邻于其位置后面的元素。
三、线性表的存储结构
- 顺序存储结构: 用一段地址连续的存储单元依次存储线性表的数据元素;
- 链式存储结构: 将数据与后继数据的存储地址以结点形式合并,用不连续的存储单元存储线性表。
四、链式存储结构的相关概念
- 链式头指针: 指向链表第一个结点(头结点)的指针,无论链表是否为空,头指针必须存在且不为空。由于具有标识作用,所以一般将头指针冠以链表的名字;
链式头结点: 数据域无意义,指针域指向第一元素地址。为了统一第一节点的插入、删除操作而设立,不是链表的必须要素。 - 单链表: 最常规形式的链表,其头结点数据域存储链表长度或无意义,终端结点指针端数据为空指针;
- 静态链表: 用数组形式描述的链表。以数组下标,替代单链表中的后续结点地址。相邻结点的位置与存储地址无关,在插入和删除结点时,不需要像顺序存储结构那样,移动大量元素,只修改数组下标(“游标”)即可。但在初始化定义时,需要估算链表的最大可能长度,以开辟数组空间;
- 循环链表: 将单链表中终端结点的指针端,由空指针改为指向头结点,使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表;
- 双向链表: 在单链表的每个结点中,再设置一个指向其前驱结点的指针域。故双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱,实现双向的结点搜寻。
五、特殊线性表
1. 栈
1.1 栈的定义
栈是限定仅在表尾进行插入和删除操作的线性表,又称后进先出(Last In First Out)的线性表,简称LIFO结构。
1.2 栈的相关概念
- 空栈: 不含任何数据元素的栈;
- 栈顶(top): 栈中允许插入和删除的一端;
- 栈底(bottom): 与栈顶相对的,位于栈另一头的数据端;
- 进栈(push): 栈的插入操作,也称压栈、入栈;
- 出栈(pop): 栈的删除操作,也称弹栈。
1.3 特殊形式栈以及对应状态
1.3.1 共享空间栈
将一段长度为n的数组空间的两端——0、n-1,分别作为两个栈(记为栈1、栈2)的栈底。两个栈共享数组空间,增加元素时,对应栈顶向中间延伸。
- 空栈:
栈1栈顶指针值等于-1,栈2栈顶指针值等于n。 - 满栈:
① 栈1为空栈时,栈2栈顶指针值等于0;
② 栈2为空栈时,栈1栈顶指针值等于n-1;
③ 栈1、栈2不为空时,两者栈顶指针值相差1。
1.3.2 链栈
以头结点为栈顶,按链式存储结构实现的栈。
注意: 链栈头结点数据段为有意义数据,区别于链表。
- 空栈:
头指针(注意:不是头结点指针)指向空。 - 满栈:
除非计算机没有任何可以使用的空间,濒临崩溃,否则理论上链式存储结构不存在满栈的情况。
2. 队列
2.1 队列的定义
队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表,又称先进先出(First In First Out)的线性表,简称FIFO结构。
2.2 队列的相关概念
- 空队列: 不含任何数据元素的队列;
- 队头: 队列中允许删除的一端;
- 队尾: 队列中允许插入的一端。
- 入队: 队列的插入操作;
- 出队: 队列的删除操作。
2.3 特殊形式队列以及对应状态
2.3.1 循环队列
分别使用两个指针,表示队头元素、队尾的下一个元素的位置。插入时,若尾部指针,越过了可利用内存的边界,先回到空间头部,再将数据入队。构成头尾相接的特殊顺序存储结构。
注意: 由于尾部指针指向的是队尾元素的下一个位置,这使得循环队列满时,头部指针与尾部指针重合,与空队列时的特征一致。为了区分两种状态,采用以下方法:
① 设置一个标志变量flag,表示队列状态。当flag为0时,表示队列无数据,此时头、尾部指针重合则认为队列空。反之,认为队列满;
② 修改队列满的条件——保留一个元素空间,即当队列满时,数组中还有一个空闲单元。此时若头部、尾部指针值差值的绝对值为1,认为队列满。(常用)
2.3.2 链队列
队列的链式存储结构,本质上是一个尾进头出的线性单链表。链队列的头部指针指向头结点,尾部指针指向终端结点。
注意: 链队列头结点数据段为有意义数据,区别于链表。