1.线性表的概念
线性表的逻辑结构
线性表(Linear List):线性表是n个类型相同数据元素的有限序列,对n > 0,除第一个元素无直接前驱、最后一个元素无直接后继外,其余的每个数据元素只有一个直接前驱和一个直接后继,数据元素之间具有一对一的关系。线性表中元素的个数n被定义为线性表的长度,n = 0时称为空表。
线性表的特点:
#同一性:线性表由同类数据元素组成,每一个元素必须属于同意数据类型
#有穷性:线性表由有限个数据元素组成,表长度就是表中数据元素的个数
#有序性:线性表相邻数据元素之间存在着序偶关系
2.线性表的顺序存储
2.1线性表的顺序存储结构
线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表中在逻辑结构上相邻的数据元素存储在连续的物理存储单元中,就是说通过数据元素物理存储的连续性来反映数据元素之间逻辑上的相邻关系。
顺序表存储示意图
2.1.1地址的计算
假设线性表中有n个元素,每个元素占k个单元,第一个元素的地址为Loc(a1),则可通过公式计算出第i个元素的地址Loc(ai),Loc(a1)为基地址。
Loc(ai) = Loc(a1) + (i - 1) * k
2.1.2线性表顺序存储的表示
#define MAXSIZE 100 //宏定义常量表示线性表的最大长度
typedef struct {
ElemType elem[MAXSIZE]; //线性表占用的数组空间
int length; //数组长度
} SeqList;
2.2线性表顺序存储结构上的基本运算
2.2.1查找操作
#按序号查找GetData(L,i);查找顺序表L中第i个元素
#按内容查找Locate(L,e);查找顺序表L中与给定值e相等的数据元素
//按内容进行查找
int locate(SeqList L,ElemType e){
//可以使用for或者while
int i = 0;
while((i <= L.length - 1) && (L.elem[i] != e))
i++; //顺序扫描表,直到找到e的元素
if(i <= L.length - 1)
return(i + 1); // 找到就返回序号
else
return(-1); //没找到,返回空序号
}
2.2.2插入操作
线性表的插入运算是指才表的第i(1 <= i <= n+1)个位置前插入一个元素e,使长度为n的线性表变成长度为n+1的线性表
//通过指针变量定义语句
#define Ok 1;
#define ERROR 0;
int InsertList(SeqList *L,int i,ElemType e){
//判断插入位置是否合法
if((i < 1) || (i > L -> length)){
printf("插入位置不合法");
return ERROR;
}
if(L -> length > MAXSIZE){
printf("表已经满了");
return error;
}
int k = 0;
for(k = L -> length - 1;k > i;k--){
//位置后移
L -> elem[k+1] = L -> elem[k];
}
L -> elem[i - 1] = e;
L -> length ++;
return (OK);
}
2.2.3删除运算
int DelList(SeqList *L,int i,ElemType *e){
//判断插入位置是否合法
if((i < 1) || (i > L -> length)){
printf("插入位置不合法");
return ERROR;
}
int k = 0;
*e = L -> elem[i - 1];//将被删除的元素放到e指向的变量中
for(k = i;k < L->length;k++){
L -> elem[k - 1] = L -> elem[k]; //后面的元素前移
}
return (OK);
}
线性表顺序表示的优点
#无须为表示结点间的逻辑关系而增加额外的存储空间
#可方便的随机存取顺序表中的每一个值
线性表顺序表示的缺点
#插入和删除不方便
#由于顺序表要求占用连续的存储空间,存储分配只能预先进行静态分配