线性结构定义及特点
线性表的定义:由n(n>=0)个数据特性相同的元素构成的有限序列。n=0时为空表。
线性结构示意图
对于非空的线性表或线性结构,其特点是:
存在唯一的一个被称作“第一个”的数据元素;
存在唯一一个被称作“最后一个”的数据元素;
除第一个之外,结构中的每个数据元素均只有一个前驱;
除最后一个之外,结构中的每个数据元素均只有一个后继
线性表的基本操作
ADT list
{
数据对象:D={ai|i=1,2,3...,n,n>=0}
数据关系:R={<ai-1,ai>|i=1,2,3,...,n,n>=0
基本操作:
{
InitList(&L): 初始化操作,构造一个空的线性表L。
DestroyList(&L):销毁线性表
ClearList(&L):将L重置为空表
ListEmpty(L):若L为空表,返回ture,否则返回false.
ListLength(L):返回L中数据元素个数
GetElem(L,i,&e): 用e返回L中第i个数据元素的值。
LocateElme(L,e): 返回L中第1个值与e相同的元素在L中的位置,若不存在,返回值为0.
PriorELem(L,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的每个结点访问一次
}ADT List
线性表的顺序存储表示(顺序表):
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像。通常,称这种存储结构的线性表为顺序表(Sequential List)
特点是:逻辑上相邻的数据元素,其物理次序也是相邻的
假设线性表中每个元素需要占用c个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储起始位置。则线性表中第i+1个数据元素与第i个数据元素的关系如下:
LOC(ai+1) = LOC(ai) + l
一般来说,线性表的第i个数据元素ai的存储位置为:
LOC(ai)=LOC(ai)+(i - 1) × l
只要确定了存储线性表的起始位置,线性表中任意数据元素都可随机存取,所以线性表的顺序存储结构是一种随机存储结构。
# 顺序表的存储结构
#define MAXSIZE 100//顺序表可能达到的最大长度
typedef struct{
ElemType &elem;//存储空间的基地址,也可以其他数据类型定义
int length;//当前长度
}SqList;//顺序表的结构类型为SqList
顺序表中基本操作的实现
1、初始化
:构造一个空的顺序表。
算法步骤:
1)为顺序表L动态分配一个预定义大小的数组空间,是elem指向这段空间的基地址。
2)将表的当前长度设为0。
算法描述
bool InitList(SqList &L )//初始化:构造一个空的顺序表
{
L.elem= new int[MAXSIZE]; //分配空间 指针变量 = new 数据类型
if(!L.elem)
return false;
L.length = 0;
return true;
也可用Status,先规定一下预定义常量及类型
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2 //Status函数的返回值是这六种类型的数
Status函数类型需要我们自己定义:typedef int Status
然后初始化就可以写作:
Status InitList(SqList &L )
{
L.elem= new int[MAXSIZE];
if(!L.elem)
exit(OVERFLOW);
L.length = 0;
return OK;
2、取值
1)判断指定的位置序号i值是否合理(1<= i <= L.length),若不合理,则返回ERROR
2) 若i值合理,则将第i个数据元素L.elem[i-1]赋给参数e,通过e返回第i个数据元素的传值
算法描述
bool GetElem(SqList L ,int i, int &e)//取值
{
if(i<1||i>L.length)
return false;
e=L.elem[i-1];
return true;
}
3、查找
1)从第一个元素开始依次和e相比较,查找顺序表中第一个与e相等的元素。查找成功返回位置序号,否则,返回0
2) 若查遍整个顺序表在表中的序号都没有找到,则查找失败,返回0
算法描述
int LocateElem(SqList L,int e)//查找或定位元素e
{
for(int i = 0;i < L.length;i++)
if(L.elem[i] == e)
return i+1;//查找成功,返回序号i+1
return 0; //查找失败,返回0(查遍整个顺序表)
}
4、插入
1)判断插入位置是否合法(1 <= i <= n+1),若不合法则返回ERROR
2)判断顺序表是否已满,若满返回ERROR
3)将第n个至第i个位置的元素依次向后移动一个位置,空出第i个位置(i=n+1时无需移动)
4)将要插入的新元素e放入第i个位置
5)表长加1
算法描述
bool ListInsert(SqList &L,int i,int e)//插入
{
if((i<1)||(i>L.length+1))
return false;//i值不合法
if(L.length==MAXSIZE)
return OVERFLOW;//当前存储空间已满
for(int j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j];//插入位置及之后元素后移
L.elem[i-1]=e;//将新元素e放入第i个位置
L.length++;
return true;
}
5、删除
1)判断位置是否合法(1 <= i <= n),若不合法返回ERROR
2)将第i+1个至第n个元素依次向前移动一个位置(i=n时,无需移动)
3)表长减1
算法描述:
bool ListDelete(SqList &L,int i)//删除
{
if((i<1)||(i>L.length))
return false;//i值不合法
for(int j = i;j <= L.length;j++)
L.elem[j-1]=L.elem[j];//被删除元素之后的元素前移
L.length--;
return true;//表长-1
}
6、清空
将表长赋值为0
void ClearList(SqList &L)
{
L.length = 0;//清空
}
7、判断顺序表是否为空
bool ListEmpty(Sqlist L)
{
if(L.length==0)
return OK;
return ERROR;
}
线性表存储结构的优缺点:
优点:
1)随机存取表中任意元素,其存储位置可以用一个简单、直观的公式来表示
2)无须为表示中元素之间的逻辑关系而增加额外的存储空间
缺点:
1)插入或删除操作时,需移动大量元素
2)当表中数据元素个数较多且变化较大时,操作过程相对复杂,必然导致存储空间的浪费。
3)当线性表长度未知时,难以确定存储空间的容量。
顺序表的实现:
https://blog.csdn.net/weixin_45895026/article/details/103888688
内容借鉴:
1)https://blog.csdn.net/lesileqin/article/details/88075259
2)《数据结构》 严蔚敏