线性表的顺序存储
线性表的存储结构有顺序、链接、索引、散列等多种方式,顺序存储结构是其中最简单、最常见的一种。
线性表的顺序存储结构可叙述为:把线性表中所有元素按照其逻辑顺序依次存储到计算机存储器中从指定存储位置开始的一块连续的存储空间中,使得线性表中的第一个元素的位置就是被指定存储空间中的开始位置,第i个元素(2≤i≤n)被紧接着存储在第i-1个元素的存储位置的后面。
元素类型为ElemType的线性表的顺序存储类型描述:
stuuct List{
ElemType list[MaxSize]; //定义一个数组来存储线性表中的所有元素
int size; //定义一个整型变量来存储线性表的长度
}
元素类型为ElemType的线性表数组空间动态分配的顺序存储类型描述:
struct List{
ElemType list; //存储线性表元素的动态存储空间的指针
int size; //存储线性表长度
int MaxSize; //存储list数组长度,即所能存储线性表最大长度
}
顺序存储下线性表的操作实现
1.初始化线性表L,即进行动态存储空间分配并置L为一个空表
void InitList(struct List *L,int ms){
//检查ms是否有效,若无效则退出运行
if(ms < 0){
printf("ms值无效!\n");
exit(1);
}
//置线性表空间大小为ms
L->MaxSize = ms;
//动态存储空间分配,若分配失败则退出运行
L->list = (ElemType *)malloc(ms * sizeof(ElemType));
if(!L->list){
printf("动态存储分配失败!\n");
exit(1);
}
//初始化置线性表为空
L->size = 0;
}
2.清除线性表L中的所有元素,释放动态存储空间,使之成为一个空表
void ClearList(struct List *L){
if(L->list != NULL){
free(L->list); //释放存储空间
L->list = 0;
L->size = L->MaxSize = 0;
}
}
3.返回线性表L的长度,若L为空则返回0
//该函数就是返回线性表L的size域的值,它可以用表达式L->size直接代替
int SizeList(struct List *L){
return L->size;
}
4.判断线性表L是否为空,若为空则返回1,否则返回0
int EmptyList(struct List *L){
if(L->size == 0)
return 1;
else
return 0;
}
5.返回线性表L中的第pos个元素的值,若pos超出范围,则停止程序运行
ElemType GetElem(struct List *L, int pos){
if(pos<1 || pos>L->size){
//若pos越界则退出运行
printf("元素序号越界");
exit(1);
}
//返回线性表中序号为pos值的元素的值
return L->list[pos-1];
}
6.遍历输出线性表L中的每个元素
void TraverseList(struct List *L){
int i;
for(i=0;i<L->size;i++){
printf("%d",L-size[i]);
}
printf("\n");
}
7.从线性表L中查找值与x相等的元素,若查找成功则返回其位置,否则返回-1
int FindList(struct List *L,ElemType X){
int i;
for(i=0;i<L-size;i++){
if(L->list[i] == x) return i;
}
return-1
}
/*
* 若用于比较的元素类型为字符串或某个域类型为字符串,则需要用字符串比较函数strcmp
* 修改if条件表达式为(strcmp(L->list[i],x) == 0)
*/
8.把线性表L中第pos个元素的值修改为x的值,若修改成功返回1,否则返回0
int UpdatePosList(struct List *L,int pos,ElemType x){
//若pos越界则修改失败
if(pos<1 || pos>L->size)
return 0;
L->list[pos-1] = x;
return 1;
}
9.向线性表L的表头插入元素x
/*
操作过程
1.检查线性表存储空间是否已满,若已满则重新分配更大的存储空间
2.移动元素位置,将下标为0的位置空出
3.将x写入表头
4.修改线性表长度,使其增1
*/
void InsertFirstList(struct List *L,ElemTypr x){
int i;
if(L->size == L->MaxSize)
//重新分配存储空间
againMalloc(L);
for(i=L->size-1;i>=0;i--)
//元素后移
L->list[i+1] = L->list[i];
L->list[0] = x;
l-size++;
}
void againMalloc(struct List *L){
//空间扩展为原来的2倍,并有p指针所指向,原内容被自动拷贝到新的存储空间中
ElemTpye *p=(ElemType *)realloc(L->list,2*L->MaxSize*sizeof(ElemType));
//若分配失败
if(!p){
printf("存储空间用尽!\n");
exit(1);
}
L->list = p;
L-MaxSize = 2*L->MaxSize;
}
10.向线性表L的表尾插入元素x
void InsertLastList(struct List *L){
if(L->size == L->MaxSize)
//重新分配空间大小
againMalloc(L);
L->list[L->size] = x;
l->size++;
}
11.向线性表L中第pos个元素位置掺入元素x,若插入成功返回1,否则返回0
/*
1.检查pos是否越界
2.检查线性表是否已满
3.从表尾向前至pos-1位置,每个元素向后移动一个位置
4.将x写入pos个元素位置,即下表为pos-1的位置
5.修改线性表长度,使其增1
6.返回1表示插入成功
*/
int InsertPosList(struct List *L, int pos, ElemType x){
int i;
//若pos越界则插入失败
if(pos<1 || pos>L->size+1)
return 0;
//若已满,重新分配存储空间
if(L->size == L->MaxSize)
againMalloc(L)
//从表尾向前至pos-1位置,每个元素向后移动一个位置
for(i=L->size-1;i>=pos-1;i--){
L->list[i+1] = L->list[i];
}
L->list[pos-1] = x;
l->size++;
return 1;
}
12.向有序线性表L中插入元素x,使得插入后任然有序
/*
1.检查表空间是否用完
2.采用顺序产找法找出x得插入位置
3.从表尾到插入位置,元素后移
4.把新元素插入到查找到得位置上
5.修改线性表长度,使其增1
*/
void InsertOrderList(struct List *L , ElemType x){
int i,j;
if(L->size == L->MaxSize)
againMalloc(L);
//顺序查找出x得插入位置
for(i=0;i<L->size;i++){
if(x<L->list[i]) break;
}
//后移元素
for(j=L->size-1;j>=i;j--)
L->list[j+1] = L->list[j];
L->list[i] = x;
l->size++;
}
13.从线性表L中删除表头元素并返回它,若删除失败则停止程序运行
/*
1.检查线性表是否为空,若是则给出错误信息并停止执行
2.把表头元素赋值给一个临时变量暂时存放
3.从第二个元素到最后一个元素,依次向前移动一个位置
4.修改线性表长度,使其减1
5.返回表头元素
*/
ElemType DeleteFirstList(struct List *L){
ElemType temp;
int i;
if(L->size == 0){
printf("线性表为空,不能删除!\n");
exit(1);
}
temp = L->list[0];
//从第二个元素到最后一个元素,依次向前移动一个位置
for(i=1;i<L->size;i++)
L->list[i-1] = L->list[i];
L->size--;
return temp;
}
14.从线性表L中删除表尾元素x并返回它,若删除失败则停止程序运行
ElemType DeleteLastList(struct List *L){
if(L->size==0){
prinf("线性表为空,不能删除!\n");
exit(1);
}
L->size--;
return L->list[L->size];
}
15.从线性表L中删除第pos个元素并返回它,若删除失败则停止程序运行
/*
1.检查pos的值是否有效
2.把pos的值暂时保存,以便删除后返回
3.从第pos+1个元素位置开始至表尾元素,依次前移一个位置
4.修改线性表长度,使其减1
5.返回暂时保存的第pos个元素的值
*/
ElemType DeletePosList(struct List *L,int pos){
ElemType temp;
int i;
if(pos<1 || pos>L->size){
printf("pos值越界!");
exit(1);
}
//把pos的值暂时保存,以便删除后返回
temp = L->list[pos-1];
//从第pos+1个元素位置开始至表尾元素,依次前移一个位置
for(i=pos;i<L->size;i++)
L-list[i-1] = L->list[i];
L->size--;
return temp;
}
16.从线性表L中删除值为x的第一个元素,若删除成功返回1否则返回0
int DeleteValueList(struct List *L ,ElemType x){
int i,j;
//查找值为x的第一个元素
for(i=0;i<L-size;i++)
if(L->list[i] == x) break;
//若查找失败则表明不存在值为x的元素,返回0
if(i == L->size) return 0;
//删除值为x的元素
for(j=i+1;j<L->size;j++)
L->list[j-1] = L->list[j];
L->size--;
return 1;
}