一、基本概念
1、线性表定义:线性表是有n个类型相同数据元素的有限序列。记作:(a1,a2,a3..ai...an),n为线性长度。
2、特点:线性结构是最简单,最直接的数据关系,数据元素之间一一对应。
同一性:由同类数据元素组成,每个ai必属于同一数据对象。
有穷性:有限个数据元素组成,表长度就是数据元素个数。
有序性:相邻元素间有序偶关系<ai,ai+1>。
3、直接前驱:除了第一个外,集合中的每个数据元素均只有一个前驱。
4、直接后继:除了最后一个,集合中每个数据元素均只有一个后继。
5、长度:该序列中所含元素的个数叫做线性表的长度。
6、空表:长度n为0时,线性表为空表。
对于线性表的基本操作有:初始化、销毁、置空、判空、求长度、查找、存取、插入、删除。
顺序存储结构的定义:用一组地址连续的存储单元依次存储线性表中的各元素。
顺序存储结构:结点顺序存取、关系线性存取。对线性表顺序存储结构C语言描述:(类型是一种规格的定义,变量是一种空间的定义)
#define MAXSIZE 100
typedef struct{
Elemtype elem[MAXSIZE];
int last;
}Seqlist;
二、线性表顺序存储结构的基本运算
1、查找
(1)按序号查找GetData( L,i )
要求查找线性表L中第i个数据元素,其结果L.elem[i-1]。
(2)按内容查找Locate(L,e)
思想:在顺序表L中依次存放着各元素,在表中查找与e相等的元素,若L[i]=e,则找到该元素,并返回i的值,若找不到,返回-1。
int Locate(Seqlist L,Elemtype e)
{
i=0; //i为扫描计数器,从第一个元素开始,数组第一个下标为0
while((i<=L.last)&&(L.elem[i]!=e))
i++;
if(i<=L.last)
return(i+1);
else
return(-1);
}
2、插入
长度为n的线性表(e1,e2...ei-1,ei...en)
长度为n+1的线性表(e1,e2...ei-1,e,ei...en),在表的第i个位置之前插入值为e的元素。
思想:(1)定位:定位到插入位置第i个元素,
(2)移动:从插入位置i-1到表末尾L->last都后移一位,
(3)插入:插入元素到L.elem[i-1]。
int InList(Seqlist *L,int i,Elemtype e)
{
//在顺序表L中第i个数据元素之前插入一个元素e,表长n=L->last+1
int k;
if((i<1)||(i>L->last+2)) //i的合法取值范围1<= i <=L->last+2
{
printf("插入位置不合法");
return(ERROR);
}
if(L->last>=maxsize-1)
{
printf("表已满无法插入");
return(ERROR);
}
for(k=L->last;k>=i-1;k--)
L->elem[k+1]=l->elem[k];
L->elem[i-1]=e;
L->last++;
return(OK);
}
3、删除
长度n (e1,e2...ei-1,ei,ei+1...en)
长度n-1(e1,e2...ei-1,ei+1...en),在表的第i个位置删除值为e的元素。
int Dellist(Seqlist *L,int i,Elemtype e)
{
//顺序表L中删除第i个元素,并用指针参数e返回其值
int k;
if((i<1)||(i>L->last+1))
{
printf("插入位置不合法");
return(ERROR);
}
//将删除的元素存入e所指向的变量中
*e=L->elem[i-1];
for(k=i;k<=L->last;k++)
L->elem[k-1]=L->elem[k];//后面的元素依次前移
L->last--;
return(OK);
}
4、合并
两顺序表LA、LB,递增有序,将它们合并成一个递增有序LC。
思路:(1)初始化:LC空表,设LC表的指示器k=0,
(2)比较循环:LA.elem[i]和LB.elem[j]两元素进行比较,较小的入LC表的指示器
void merge(Seqlist *LA,Seqlist *LB,Seqlist *LC)
{
int i=0,j-0,k=0;
while(i<=LA->last&&j<=LB->last)
/*比较循环*/
if(LA->elem[i]<=Lb->elem[j])
{
LC->elem[k]=LA->elem[i];
i++;
k++;
}
else
{
Lc->elem[k]=LB->elem[j];
j++;
k++;
}
/*当LA比LB长时,将LA余下元素赋给LC*/
while(i<=LA->last)
{
LC->elem[k]=LA->elem[i];
i++;
k++;
}
/*当LB比LA长时,将LB余下元素赋给LC*/
while(j<=LB->last)
{
LC->elem[k]=LB->elem[j];
j++;
k++;
}
LC->last=LA->last+Lb->last+1;
}
线性表的顺序存储结构的优缺点,优点:无需为表示结点间逻辑关系而增加额外的存储空间,可方便地随机存取查找表中的任一元素。缺点:除表尾之外插入删除效率低,静态分配。
顺序表中需注意的几点:
(1)长度n的顺序表中的第i个(1<=i<=n+1)位置插入1个元素,需要移动 n-i-1 个元素。
(2)删除长度n的顺序表中元素的概念相同,则删除一个元素平均要移动 (n-1)/2 个元素。
(3)顺序表中第一个元素地址若为Base,每一个结点占m个单元,则第i个结点的地址为 Base+(i-1)*m 。