定义
- 由n(n>=0)个数据特性相同的元素构成的有序数列称为线性表
- 线性表中元素的个数n(n)定义为线性表的长度,n=0时称为空表
特点
(对于非空的线性表和线性结构)
(1)存在唯一的一个被称作“第一个”的数据元素
(2)存在唯一的一个被称作“最后一个”的数据元素
(3)除第一个之外,结构中的每个数据元素均只有一个前驱
(4)除最后一个之外,结构中的每个数据元素均只有一个后继
类型定义
- 基本操作
InitList(&L)
构造一个空的线性表L
DestroyList(&L)
销毁线性表L
ClearList(&L)
将L重置为空表
ListEmpty(L)
若L为空表,则返回true,否则返回false
ListLength(L)
返回L中的数据元素个数
GetElem(L,i,&e)
用e返回L中第i个数据元素的值
LocateElem(L,e)
返回L中第1个值与e相同的元素在L中的位置。若这样的数据元素不存在,则返回值为0
PriorElem(E,cur_e,&pre_e)
若cur_e是L的数据元素,且不是第一个,则用pre_e返回其前驱,否则操作失败,pre_e无定义
NextElem(L,cur_e,&next_e)
若cur_e是L的数据元素,且不是最后一个,则用next_e返回其后继,否则操作失败,next_e无定义
ListInsert(&L,i,e)
在L中第i个位置之前插入新的数据元素e,L的长度增加1
ListDelete(&L,i)
删除L的第i个数据元素,L的长度减1
TraverseList(L)
对线性表L进行遍历,在遍历过程中对L的每个结点访问一次
顺序存储表示
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像。通常,称这种存储结构的线性表为顺序表。其特点为逻辑上相邻的数据元素其物理次序也是相邻的。
假设线性表的每个元素需占用 l 个存储单元
第 i+1 个元素的存储位置和第 i 个数据元素的存储位置之间的关系为:LOC( ai+1 )=LOC( ai )+ l
即为
- LOC( ai )=LOC( ai )+ ( i-1 )*l
(每一个数据元素的存储位置都和线性表的起始位置相差一个常数,这个常数和数据元素在线性表中的位序成正比。所以,只要确定了存储线性表的起始位置,线性表中任一数据元素都可随机存取,即线性表的顺序存储结构是一种随机存取的存储结构。)
顺序表基本操作的实现
表的长度是顺序表的一个“属性”,可通过返回 length 的值实现求表长的操作,通过判断 length 的值是否为0来判断表是否为空。这些操作算法的时间复杂度均为O(l)
( 顺序表缺点:在做插入和删除操作时,需要动大量元素)
- 初始化
Status InitList(SqList &L)
{ //构造一个空的顺序表L
L.elem = new ElemType[MAXSIZE] //为顺序表分配一个大小为MAXSIZE的数组空间
if(!L.elem) exit(OVERFLOW) //存储分配失败
L.length=0; //空表长度为0
return OK;
}
(动态分配线性表的存储区域可以更有效地利用系统的资源,当不需要该线性表时,可以使用销毁操作及时释放占用的存储空间。)
- 取值
Status GetElem(SqList L ,int i ,ElemType &e)
{
if(i<1 || i>L.length) return ERROR; //判断i值是否合理,若不合理,返回ERROR
e=L.elem[i-1]; //elem[i-1]存储第i个数据元素
return OK;
}
- 顺序表取值算法的时间复杂度为O(l)
- 查找
int LocateElem(SqList L,ElemType e)
{ //在线性表L中查找值为e的数据元素,返回其序号
for(i=0 ;i<L.length ;i++)
if(L.elem[i] == e) return i+1; //查找成功,返回序号i+1
return 0; //查找失败,返回0
}
ASL=(n+1)/2
(在查找时,为确定元素在顺序表中的位置,需和给定值进行比较的数据元素个数的期望值称为查找算法在查找成功时的平均查找长度(ASL))
- 顺序表按值查找算法的平均时间复杂度为O(n)
- 插入
Status ListInsert(SqList &L,int i,ElemType e)
{ //在顺序表L中第 i 个位置插入新的元素e,i值的合法范围是1~L.length+1
if( (i<1)||(i>L.length+1) ) return ERROR; //i值不合法
if(L.length == MAXSIZE) return ERROR; //当前存储空间已满
for( j=L.length-1 ;j>=i-1 ;j--)
L.elem[j+1] = L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1] = e; //将新元素 e 放入第 i 个位置
++L.length; //表长加1
return OK;
}
在长度为 n 的线性表中插入一个元素时所需移动元素次数的期望值(平均次数)= n/2
(上述算法没有处理表的动态扩充,因此当表长已经达到预设的最大空间时,则不能再插入元素。)
-
顺序表插入算法的平均时间复杂度O(n)
-
删除
Status ListDelete(SqList &L,int i)
{ // //在顺序表L中删除第 i 个元素,i值的合法范围是1~L.length
if( (i<1) || (i>L.length) ) return ERROR;
for(j=i ;j<=L.length-1 ;j++)
L.elem[j-1]=L.elem[j]; //被删除元素之后的元素前移
--L.length; //表长减1
return OK;
}
(在长度为 n 的线性表中删除一个元素所需移动元素次数的期望值(平均次数)= (n-1)/2 )
- 顺序表删除算法的平均时间复杂度O(n)