线性表的定义和特点
同一线性表中的元素必定有相同的特性,即属于统一数据对象,相邻数据元素之间存在着序偶关系。
由n(n>=0)个数据特性相同的的元素构成的有限序列称为线性表
线性表中元素的个数n(n>=0)定义为线性表的长度,n=0时称为空表
线性结构示意图:
对于非空的线性表或线性结构,其特点
是:
- 存在唯一的一个被称为“第一个”的数据元素;
- 存在唯一的一个被称为“最后一个”的数据元素;
- 除第一个之外,结构中的每个元素均只有一个前驱;
- 除最后一个之外,结构中的每个元素均只有一个后继。
线性表的抽象数据类型定义
ADT 线性表 (list)
- Data 线性表的数据(Date)对象集合为 {a1,a2,a3,a4…,an},每个元素的类型均为DataType。
- 其中,除了第一各元素a1以为每个元素有且只有一个直接前驱元素,除了最后一个元素an以外,每个元素有且只有一个直接后继元素。
- 数据元素之间的关系是一对的关系。
Operation(基本操作)
InitList(*L):初始化操作,生成一个空的线性表L。
ListEmpty(L):判断是否为空表,如果是就返回ture,如果不是就返回lfalse。
ClearList(*L):将线性表清空。
GetElem(L,i,*e):将线性表L中的第i个节未知元素值返回给e。
LocateElem(L,e):在线性表中查找与给定值e相等的元素,如果查找成功,返回元素在表中的序号表示成功;否则返回0表示失败。
ListInsert(*L,i,e):在线性表L中第i个位置插入新的元素e。
ListDelete(*L,i,*e):删除线性表L中第i个位置元素,并返回其值给e。
Listlength(L):返回线性表L的元素个数。
线性表的顺序存储表示(顺序表)
线性表的顺序表示指的是用一组
地址连续
的存储单元依次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像。通常,称这种存储结构的线性表为顺序表
(Sequential List)。其特点是,逻辑上相邻的数据元素,其物理次序也是相邻的。
地址计算方法:假设线性表中每个元素需要占用c个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储起始位置。则线性表中第i+1个数据元素与第i个数据元素的关系如下:
LOC() = LOC() + c
一般来说,线性表的第i个数据元素的存储位置为:
LOC()=LOC()+(i - 1) * c
每一个数据元素的存储位置都和线性表的起始位置相差一个常数,这个常数和数据元素在线性表的位序成正比。由此,只要确定了存储线性表的起始位置,线性表中任一数据元素都可随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。
顺序表中基本操作的实现
1.初始化:
【算法步骤】
- 为顺序表L动态分配一个预定义大小的数组空间,使elem指向这段空间的基地址。
- 将表的当前长度设为0。
【算法描述】
Status InitList(SqList &L)
{//构造一个空的顺序表L
L.elem = new ElemType[MAXSIZE];//为顺序表分配一个大小为 MAXSIZE的数组空间
if(!L.elem) exit(OVERFLOW); //存储分配失败退出
L.length = 0; //空表长度为0
return OK;
}
2.取值:
【算法步骤】
- 判断指定位置的位置序号i值是否合理(1<=i<=L.length),若不合理,则返回ERROR
- 若i值合理,则将第i个数据元素L.elem[i-1]赋给参数e,通过e返回第i个数据元素的传值
Status GetElem(Sqlist L,int i,ElemType &e)
{
if(i<1||i>L.length) //判断i是否合理
return ERROR;
e=L.elem[i-1]; //elem[i-1]单元存储第i个数据元素
return OK;
}
3.查找:
【算法步骤】
- 从第一个元素起,依次和e相比较,查找顺序表中第一个与e相等的元素。查找成功返回该元素在表中的位置序号,否则,返回0
- 若查遍整个顺序表有找到,则查找失败,返回0。
【算法描述】
int LocateElem(Sqlist L,ElemType e)
{//在顺序表L中查找值为e的数据元素,返回其序号
for(int i=0;i<L.length;i++) //遍历整个顺序表
if(L.elem[i]==e) return i+1; //如果查到,返回i+1
return 0; //没有查到,返回0
}
4.插入:
【算法步骤】
- 判断插入位置i是否合法(i值的合法范围是1<=i<=n+1),若不合法则返回ERROR。
- 判断顺序表是否已满,若满返回ERROR。
- 将第n个至第i个位置的元素依次向后移动一个位置,空出第i个位置(i=n+1时无需移动)
- 将要插入的新元素e放入第i个位置。
- 表长加1。
【算法描述】
Status ListInsert(Sqlist &L,int i,ElemType e)
{//在顺序表L中的i个位置插入元素e,i值的合法范围是1<=i<=L.length+1
if(i<1||i>L.length+1) return ERROR; //i值不合法
if(L.length==MAXSIZE) return ERROR; //当前存储空间已满
for(int j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j]; //插入位置及之后元素后移
L.elem[i-1]=e; //将新元素放入第i个位置
L.length++; //表长加一
return OK;
}
5.删除:
【算法步骤】
- 判断位置是否合法(合法值为1 <= i <= n),若不合法返回ERROR
- 将第i+1个至第n个元素依次向前移动一个位置(i=n时无需移动)
- 表长减1
【算法描述】
Status ListDelete(Sqlist &L,int i)
{//在顺序表L中删除第i个元素,i值的合法范围是1<=i<=L.length
if(i<1||i>L.length+1) return ERROR; //i值不合法
for(int j=i;j<L.length;j++)
L.elem[j-1]=L.elem[j]; //被删除元素之后的元素前移
L.length--; //表长减1
return OK;
}
6.清空数据表L:
void ClearList(SqList &L)
{
L.length=0; //将线性表的长度设为0
}
7.求顺序表L的长度:
int GetLength(SqList.L)
{
return (L.length);
}
8.销毁顺序表L:
void DestroyList(SqList &L)
{
if(l.elem) delete [] L.elem; //释放存储空间
}
顺序表的简单实现见下篇博客。。。。。。。。