目录
1 线性表的定义和基本操作
1.1 定义
线性表的定义(2-1):线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列。
- 注意,线性表是一种逻辑结构,它只有(2-1)这句定义,表示元素之间一对一的相邻关系
- 之后我们学习的顺序表和链表才指存储结构,所以线性表只考虑逻辑方面的关系
1.2 基本操作
1.3 小结
2 线性表的顺序表示和实现
2.1 顺序表示
1)存储结构
- 顺序表就是用一组地址连续的存储单元依次存储线性表中的数据元素
- ① 线性表 + 顺序存储 = 顺序表
- 数据元素现在不仅是逻辑上 按序 且 前后相邻,而且物理上也是 按序 且 前后相邻,顺序表用一块连续的存储空间顺序****实现线性表
- ② 线性表的顺序存储 + 元素类型相同 = 随机存取
- ③ 存储空间分配方式
- 顺序表在高级语言中是使用数组来实现的,根据对顺序表存储空间分配方式的不同,分成静态分配和动态分配
- 静态分配时,数组的大小在一开始是固定的,空间满了数据就会溢出;
- 动态分配时,存储数组的空间是在程序执行过程中通过动态存储分配语句分配的,不够在扩充。
- 这里就有一处很重要的地方需要注意,当动态分配的数组空间不够用的时候,想再扩充L个存储空间(数组N个存储空间),这时候程序是在内存开辟一个N+L大小的空间,而不是L大小。因为顺序表就得占用着一块连续的内存空间
2)静态分配
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MaxSize 10 //定义顺序表的长度
typedef struct {
int data[MaxSize];//用静态的数组存放元素!
int length;
}SqList;
//相当于python中的类,这个类有一个属性是 长度
//基本操作--初始化一个顺序表
void InitList(SqList& L) {
for (int i = 0; i < MaxSize; i++) {
L.data[i] = 0;
}//初始化每一个值为0
L.length = 0;
}
//主函数
int main() {
SqList L;//创建一个顺序表
InitList(L);//初始化一个顺序表!!!
return 0;
}
3)动态分配
#include <bits/stdc++.h>
using namespace std;
#define INITSIZE 10
typedef struct
{
int val;
} ElemType;
typedef struct
{
ElemType *data;
int length;
int maxSize;
} SqList;
void InitList(SqList &list)
{
list.data = (ElemType *)malloc(INITSIZE * sizeof(ElemType));
list.length = 0;
list.maxSize = INITSIZE;
}
int main()
{
SqList l;
InitList(l);
int elem, i = 0;
while (cin >> elem)
{
l.data[i].val = elem;
l.length++;
i++;
}
for (i = 0; i < l.length; i++)
{
cout << "data[" << i << "] = " << l.data[i].val << endl;
}
}
4)小结
2.2 基本操作实现
1)插入
2)删除
3)查找
- ① 按位查找
静态:
动态分配:
- ② 按值查找
4)小结
3 线性表的链式表示和实现
3.1 单链式表示
1)存储结构
2)代码定义
3)不带头结点的初始化
4)带头结点的初始化
5)小结
头结点不存储数据,不带头结点那么这个头指针指向的就是实际用于存放数据的结点而带头结点 这个头指针指向的是头结点 这个结点不存放数据,这个头结点之后的下一个结点才会用于存放数据!!!
3.2 单链表基本操作
- 对于不带头结点的情况,虽然考查较少,当也有可能考
- 除了插入操作有带头、不带头情况,其它操作默认带头结点
1)插入
- ① 带头结点
- ② 不带头结点
- ③ 指定后插
- ④ 指定前插
- 该方法虽然间接实现了指定结点的前插操作,但是无法获得前驱结点的指针
2)删除
- ① 带头结点
- ② 指定删除
- 无法删除最后一个结点
如果p是最后一个结点的话:【只能采用方法一来弄!】
3)查找
- ① 按位查找
- ② 优化插入操作代码
- ③ 按值查找
- ④ 求表长度
- ⑤ 小结
4)单链表的建立
- ① 尾插法
这样的问题是每次都要遍历到找到最后一个元素,那么时间复杂度就是0+1+2+3+.....+(n-1)这样的话时间复杂度就是o(n^2) 太高了,引入尾指针!
- 下面时间复杂度是O(n),但是如果题目说明每次都重头开始遍历进行尾插,就是O(n^2)
- ② 头插法
3.3 双链表
1)初始化
- 带头结点情况
2)插入
3)删除
4)遍历
5)小结
3.4 循环链表
1)循环单链表
2)循环双链表
- ① 初始化
- ② 插入
- ③ 删除
3)小结
3.5 静态链表
1)概念
2)定义
3)实现
4)小结
4 顺序表和链表的比较
4.1 逻辑结构
4.2 存储结构
4.3 基本操作
4.4 小结
5 线性表的应用
必定不考,放在这里主要是为了知识结构的完整性