1、线性表 List:最常用且最简单的数据结构。
含有大量记录的线性表称为文件。
2、线性表是n个数据元素的有限序列。
线性结构的特点: ①“第一个” ②“最后一个” ③前驱 ④后继。
3、顺序表——线性表的顺序存储结构
特点
a) 逻辑上相邻的元素在物理位置上相邻。
b) 随机访问。
1) typedef struct{
DataType elem[MAXSIZE];
int length;
} SqList;
2) 表长为n时,线性表进行插入和删除操作的时间复杂度为O(n)‘
插入一个元素时大约移动表中的一半元素。
删除一个元素时大约移动表中的(n-1)\2
4、线性表的链式存储结构
1) 类型定义
简而言之,“数据 + 指针”。
typedef struct LNode {
DataType data;
struct LNode *next;
} LNode, *LinkList;
2) 不带头结点的空表判定为 L= =null
带头结点的空表判定为 L->next= =null
循环单链表为空的判定条件为 L.next= =L
线性链表的最后一个结点的指针为NULL
头结点的数据域为空,指针域指向第一个元素的指针。
5、顺序表和单链表的比较
顺序表 |
单链表 |
以地址相邻表示关系 |
用指针表示关系 |
随机访问,取元素O(1) |
顺序访问,取元素O(n) |
插入、删除需要移动元素O(n) |
插入、删除不用移动元素O(n)(用于查找位置) |
6、顺序存储:
优点:存储密度大,可随机存储
缺点:大小固定;不利于增减节点;存储空间不能充分利用;容量难扩充
链式存储:
优点:易于插入删除;可动态申请空间;表容量仅受内存空间限制
缺点:增加了存储空间的开销;不可以随机存储元素
- 线性表的类型定义
- 线性表是n(n>0)个相同类型数据元素构成的有限序列,其中n为线性表的长度。
- 线性表的基本操作:
- 线性表的顺序表示和实现
- 线性表的顺序存储结构:用一组地址连续的存储单元依次存储线性表的元素。
- 线性表的顺序存储,也成为向量存储,又可以说是一维数组存储。线性表中结点存放的物理顺序与逻辑顺序完全一致,它叫向量存储。
-
- 线性表顺序存储结构在插入或删除数据元素时比较繁琐,但是它比较适合存取数据元素。
- 线性表的插入操作:在第i个元素之前插入一个元素时,需将第n至第i(共n-i+1)个元素向后移动一个位置。
- 线性表的删除操作:删除第i个元素时需将从第i+1至第n(共n-i)个元素一次向前移动一个位置
- 线性表的链式表示和实现
- 用一组任意的存储单元(可能不连续)存储线性表的数据元素。
- 在链式存储结构中,每个存储结点不仅包含数据元素本身的信息,还必须包含每个元素之间逻辑关系的信息,即包含直接后继结点的地址信息(指针域)。
- 逻辑顺序与物理顺序有可能不一致;属顺序存取的存储结构,即存取每个元素必须从第一个元素开始遍历,直到找到需要访问的元素,所以所花时间不一定相等。
- 链表的创建方式:
- 结点类的定义:
- 单链表的基本操作
- 插入方式——头插法:
- 插入方式——尾插法:
- 查找运算——按序号查找:在链表中,即使知道被访问结点的序号i,也不能像顺序表中那么直接按序号i访问结点,而只能从链表的头指针除法,顺着链域next逐个结点往下搜索,直至搜索到第i个结点为止。链表不是随机存取结构,只能顺序存取。
- 查找运算——按数值查找:
- 删除结点:将被删除结点的前驱指针连接被删除结点的后继指针
- 循环链表
- 表中尾结点的指针域指向头结点,形成一个环。从表中任意一个点出发都可以找到表中其他的结点。
- 循环链表的操作和线性链表的操作基本一致,但循环链表中没有NULL指针,故遍历操作时,终止条件不再是判断p或p.next是否为空,而是判断他们是否等于某一指定指针,如头指针或尾指针。
- 双向链表
- 双向链表是在单链表的每个结点里再增加一个指向其直接前驱的指针域prior。这样就形成了链表中有两个方向不同的链,故称为双向链表。
- 双线链表——头插法:
- 双向链表——尾插法:
-
插入操作
删除操作