顺序线性表
感性认知:
类似一个长长的队伍,这个队伍排成一条线,有头有尾,这样形式的就是线性表。
定义:
由零个(空表)或者多个元素组成的有限序列,是有先后顺序的。一个元素前面的那个元素称为前驱,后面的一个元素称为后继,头元素无前驱,最后的一个元素无后继。
线性表的存储结构
顺序存储结构:元素按照将地址的存储形式一致,例如C语言中的数组。
一个简单的线性表
#define MAXSIZE 20
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];
int lenth;//线性表的长度
}Sqlist;
顺序结构封装需要的三个属性:起始位置,最大的存储容量,线性表的当前长度。
这里与C语言数组的区别是,线性表的当前长度会随着线性表的里面的元素改变,而数组长度,确定了,一般就不会改变了。
注意:线性表是从1开始,C语言中的数组是从0开始的。
地址的计算方法
顺序线性表是需要知道某个元素所在的位置,从而推断处下个元数所在的位置,这里也就是需要知道某个元数的地址。
要是我们知道第一个元素的地址,想要求第i个元素的位置,地址的计算方法如下:
Loc(ai)=Loc(a1)+(i-1)*sizeof©
其中C为某个变量类型,只需要知道a1的地址或者某一个地址就可以知道ai的位置了。
寻找某个元素的函数C代码
#define OK 1
#define ERROR 0
typedef int Status;
typedef int len;
Status GetElem(Sqlist l,len i,Elemtype *e)
{
if(len<1||l.Len<1||i>l.Len)
return ERROR ;
*e =l.data(i-1);//注意这里的C语言数组是从0开始,而线性表从1开始。
return OK;
}
寻找插入元素的函数C代码
Status Listinsert(Sqlist l,len i,Elemtype e)
{
int k;
if(l->Len==MAXSIZE) return ERROR;
if(i<1||i>l->Len+1) return ERROR;
if(i<=l->Len)
{ for(k=l->Len-1;k>=i-1;k--)//遍历到当前元素
{
l->data[k+1]=l->data[k];
}
}
l->data[i-1]=e;
l->len++;
return OK;
}
删除元素的函数C代码
Status Listdel(Sqlist l,len i,Elemtype *e)
{
int k;
if(l->Len==0) return ERROR;
if(l->Len==MAXSIZE) return ERROR;
if(i<1||i>l->Len) return ERROR;
*e=l->data[i-1]//保持删除值
if(i<=l->Len)
{ for(k=i;k<l->Len;k++)
{
l->data[k-1]=l->data[k];//因为C语言数组是从0开始,k-1就是当前要删除元素的位置
}
}
l->len--;
return OK;
}
总结
顺序存储时,相邻数据元素的存放地址也相邻(逻辑与物理统一);要求内存中可用存储单元的地址必须是连续的。
优点:存储密度大(=1),易于查找和修改。
缺点:插入或删除元素时不方便;存储空间利用率低,预先分配内存可能造成存储空间浪费,也容易产生磁盘碎片。