线性表的顺序表示和实现
线性表的顺序表示指的是用一组地址连续的存储单元一次存储线性表的数据元素。
缺点是插入和删除时需要移动大量元素。
适用于数据相对稳定的线性表,如工资表、学籍表等。
假设
1.线性表的每个元素占有l个字节
2.以所占第一单元的存储地址作为数据元素的存储位置
则
第i个数据元素的存储位置LOC(ai)和第i+1个存储元素LOC(ai+1)关系为
LOC(ai+1) = LOC(ai) + l
LOC(ai) = LOC(a1) + (i-1) * l
一.结构体的理解
- struct有三种定义方式
1.定义结构体类型,定义结构体变量
struct data{
int month;
int year;
};//定义结构体类型
定义结构体的时候是不分配内存的
struct data a;//定义结构体变量
定义结构体变量之后才会分配内存空间
2.定义结构体类型的同时定义结构体变量
struct data{
int month;
int year;
}a;
3.直接定义结构体变量
struct {
int month;
int year;
}a;
一般用于程序中只需要这样一个结构体变量
- typedef有两种定义方式
typedef 类型名,新类型名
typedef int a// a就是int的别名
typedef 类型定义,新类型名
typedef struct {
int month;
int year;
}SqList;
SqList *l;//定义了指向结构体的指针变量
二.线性表动态分配顺序存储结构
#define LIST_INIT_SIZE 100//存储空间初始分配量
#define LISTINCREMENT 10//存储空间分配增量
typedef struct{
ElemType *elem;//存储空间基址
int length;// 存储空间当前长度
int listsize;//分配的存储容量
}SqList;
线性表的基本操作的具体实现
构造一个空的顺序线性表
分配一个预定大小的数组空间
并将线性表的当前长度设置为0
void InitList(SqList &L){
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem) exit(OVERFLOW);
L.length=0;
L.listsize=LIST_INIT_SIZE;
}
销毁一个空的顺序线性表
void DestroyList(SqList &L){
free(L.elem);//释放L.elem所指的存储空间
L.elem=NULL;//L.elem不指向任何存储单元
L.length=0;
L.listsize=0;
}
将L置为空表
void ClearList(SqList &L){
L.length=0;
}
L为空表返回True,否则返回False
Status ListEmpty(SqList &L){
if(L.length==0)return TRUE;
else return FALSE;
}
返回L中元素个数
int ListLength(SqList L){
return L.length;
}
用e返回L中第i个元素的值
Status GetElem(SqList L,int i,ElemType &e){
if(i<1||i>L.length)return ERROR;
else{
e=*(L.elem+i-1);
return OK;
}
}
返回L中第一个与e满足compare关系的数据元素位序
int LocateElem(Sqlist L, ElemType e,Statues(*compare(ElemType,ElemType))){
int i=1;
ElemType *p=L.elem;
while(i<=L.length&&!compare(*p++,e)) i++;
if(i<=L.length)return i;
else return 0;
}
找前驱,若无前驱操作失败
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e){
int i=2;
ElemType *p=L.elem+1;
while(i<=L.length&&*p!=cur_e){
p++;
i++;
}
if (i>L.length)return ERROR;
else {
pre_e=*--p;
return OK;
}
}
找后继
Status NextElem(SqList L,ElemType cur_e,ElemType &next_e){
int i=1;
ElemType *p=L.elem;
while(i<L.length&&*p!=cur_e){
i++;
p++;
}
if(i==L.length)return ERROR;
else {
next_e=*++p;
return OK;
}
}
在L 第i位置插入元素e,L长度加一
确定插入位置
插入位置之后的每个元素都右移
插入元素
顺序表长度加一
status ListInsert(SqList &L,int i, ElemType e){
int len=L.length;
ElemType *p,*q,*newbase,;
if(i<1||i>len+1)return ERROR;
if(L.length==L.listsize){
newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType))
if (!newbasa)exit(OVERFLOW);
L.elem=newbase;
L.listsize=L.listsize+LISTINCREMENT;
}//如果内存不够,分配新内存
q=L.elem+i-1;
for(p=L.elem+len-1;p>q;p--){
*(p+1)=*p;
}
*q=e;
L.length++;
return OK;
}
删除L中第i个元素,用e返回其值,L长度减一
Status ListDelete(SqList &L,int i,ElemType &e){
if(i<1||i>L.length)return ERROR;
ElemType *p,*q;
q=L.elem+i-1;//被删除元素的地址
e=*q;
for(p=q;p<=L.elem+L.length-1;p++){
*p=*(p+1);
}
L.length--;
return OK;
}