定义:用顺序存储的方式实现线性表
顺序存储:把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。
存放地址的计算:设第一个元素存放的位置是LOC(L),则第i个元素的存放地址则为:
如何知道一个数据元素的大小:利用sizeof(ElemType)
sizeof(int)
顺序表的实现
- 静态分配
#define Maxsize 10
typedef struct{
ElemType data[MaxSize];
int length;
}SqList
具体代码:
#include <stdio.h>
#define MaxSize 10 //定义最大长度
typedef struct{
int data[MaxSize]; //用静态的“数组”存放数据元素
int length; //顺序表的当前长度
}SqList //顺序表的类型定义
//基本操作:初始化一个顺序表
void InitList(SqList &L){
for(int i=0; i<Maxsize; i++) //将所有数据元素设置为默认初始值
L.data[i]=0;
L.length=0 //顺序表初始长度为0
}
int main(){
SqList L; // 声明一个顺序表
InitList(L); //初始化顺序表
//……未完待续,后续操作
}
NOTE:内存中会有遗留的脏数据 Q:如果”数组“存满了怎么办? A:放弃治疗,顺序表的表长刚开始确定后无法更改(存储空间是静态的)
- 动态分配
#define Maxsize 10
typedef struct{
ElemType *data; //指示动态分配数组的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表的当前长度
}SeqList
具体实现展示:
#include<stdlib.h> //malloc,free的头文件
#define InitSize 10
typedef struct{
int *data; //指示动态分配数组的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表的当前长度
}SeqList
void InitList(SeqList &L){
//用malloc函数申请一片连续的存储空间
L.data=(int *)malloc(InitSize*sizeof(int));
L.length=0;
L.MaxSize=InitSize
}
//增加动态数组的长度
void IncreaseSize(SeqList &L, int len){
int *p=L.data;
L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));
for(int i=0;i<L.length;i++){
L.data[i]=p[i];
}
L.MaxSize=L.MaxSize+len;
free(p); //释放原来的内存空间
}
int main(){
SeqList L;
InitList(L);
//……往顺序表中随便插入几个元素……
IncreaseSize(L,5);
return 0;
}
顺序表的插入和删除
- 插入 ListInsert(&L,i,e) —在表L的第i个位置上插入元素e
void ListInsert(SqList &L,int i,int e){
for(int j=L.length;j>=i;j--)
L.data[j]=L.data[j-1];
L.data[i-1]=e;
L.length++;
}
//优化版
bool ListInsert(SqList &L,int i,int e){
if(i<1||i>L.length+1)
return false;
if(L.length>=MaxSize)
return false;
for(int j=L.length;j>=i;j--)
L.data[j]=L.data[j-1];
L.data[i-1]=e;
L.length++;
return true;
} //具有健壮性
插入操作的时间复杂度:
最好情况:新元素插入到表尾巴,不需要移动元素
最好时间复杂度:
最坏情况:插入表头元素
平均情况:
- 删除操作
//优化版
bool ListInsert(SqList &L,int i,int &e){
if(i<1||i>L.length+1)
return false;
e=L.data[i-1]; //将被删除的数据元素复制给e
for(int j=i;j<L,length;j++)//将第i个位置后的元素前移
L.data[j-1]=L.data[j];
L.length--; //线性表长度减1
return true;
}
删除操作的时间复杂度:
最好情况:删除表尾元素,不需要移动元素
最坏情况:删除表头元素
平均情况:
顺序表的查找
- 按位查找 静态分配:
ElemType GetElem(SqList L,int i){
return L.data[i-1];
}
动态分配
ElemType GetElem(SeqList L,int i){
return L.data[i-1];
}
时间复杂度
- 按值查找
int LocateElem(SeqList L,ElemType e){
for(int i=0;i<L.length;i++)
if(L.data[i]==e)
return i+1;
return 0;
}
// 基本数据类型:int,char,double,float等可以直接运用“==”比较
时间复杂度
最好时间复杂度:
最坏:
平均:
结构类型的比较
//需要依次对比各个分量来判断两个结构体是否相等
if(a.num == b.num&&a.people==b.people){
printf("相等");
}else{
printf("不相等");
}