线性表
1. 线性表的逻辑结构
- 定义:线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列。其中n为表长。当n=0时 线性表是一个空表
- 除第一个元素,其余元素都有一个直接前驱
- 除最后一个元素,其余元素都有一个直接后继
线性表中的元素从1开始,位序也就是指在第几个位置
2. 线性表的基本操作
- 初始化表、销毁、插入、删除、按值查找、按位查找、求表长、输出、判空
*2.1 &变量的介绍
- 对参数的修改结果需要带回来,则需要使用**&**引用类型
- 形参是引用类型,则与main函数内同名变量是同一内存位置
- 形参不是引用类型,则只是main函数内同名变量的一个复制品,对应内存的不同位置,即两个不同的数据
3. 线性表的顺序存储
3.1 顺序表
-
实际就是用顺序结构实现的线性表
-
用一组地址联系的存储单元(eg:数组),依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理上也相邻
-
已知第一个元素的位置可以使用sizeof计算出数据元素的大小从而求得其它元素的位置
3.2 顺序表的实现
3.2.1 静态分配:数组的大小不可变
# define MaxSize 10 //定义最大长度
typedef struct{
ElemType data[MaxSize]; //使用静态数组存放数据元素
int length; //顺序表当前的长度
}SqList; //顺序表的类型名
SqList L; //定义一个L为顺序表
3.2.2 动态分配:数组的大小可变
# define MaxSize 10 //定义最大长度
typedef struct{
ElemType *data; //指向动态分配数组起始地址的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表当前的长度
}SqList; //顺序表的类型名
*3.2.3 key:动态申请和释放内存空间(# include <stdlib.h>)
-
malloc:
1.申请一整片连续的空间,这片空间一定有起始的内存地址,所以malloc函数执行完毕过后,会返回一个指向这一片地址空间起始地址的指针
2.mallo函数返回的指针类型需要强制转化为你定义的数据元素的类型
3.malloc函数申请空间的大小 = 所占大小 x 个数(sizeof()*size)
-
free:释放空间
L.data = (ElemType *)malloc(sizeof(ElemType)*InitSize)
3.2.4 顺序表的特点
- 随机访问:能在O(1)时间内找到第i个元素
- 存储密度高:每个节点只存数据元素,无需花费空间建立表中的元素的逻辑关系(物理位置相邻)
- 插入删除操作不方便,需要移动大量元素
3.3 顺序表的插入
- 在第i个位置插入元素e
bool ListInsert(SqList &L,int i,inte){
if(i<1||i>L.length+1) //判断i的范围是否有效
return false;
if(L.length>=MaxSize) //如果当前存储空间已满则不能插入
return true;
for(int j = L.length;j>=i;j--)
L.[j] = L.data[j-1]; //将第i个元素及之后的元素后移
L.data[i-1] = e; //在位置i处放入e
L.length++; //长度+1
return true; //插入成功返回true
}
-
时间复杂度:
最好:插入到表尾,不需要移动元素 O(1)
最坏:插入到表头,移动n个元素 O(n)
3.3 顺序表的删除
- 删除第i个位置的元素并返回其值
- 声明一个与删除变量同类型的元素将被删除的值“带回来” (int e = -1)
bool ListDlete(Sqlist &L,int i,int &e){
if(i<1||i>L.length) //判断i的范围是否有效
return false;
e = L.data[i-1]; //将被删除元素赋值给e
for(int j=i;j<L.length;j++)
L.data[j-1]=L.data[j]; //将第i个位置后的元素前移
L.length--; //线性表长度-1
return true; //删除成功
}
-
时间复杂度
最好:删除表尾元素,不需要移动元素 O(1)
最坏:删除表头元素,移动n个元素 O(n)
3.4 顺序表的查找
3.4.1 按位查找
- 获取L表中第i个元素的值
- 动态分配:用某个类型的指针+数组下标访问数据的方式,系统在后面取数据时&#