1、线性表概述
线性表就像是排队一样,具有线一样的性质。线性表是由零个或多个数据元素组成的有限序列,元素之间有先后顺序,且第一个元素没有前驱,最后一个元素没有后继,其余元素都有且仅有一个前驱和后继。另外,线性表必须是有限的。
线性表元素的个数定义为线性表的长度,当长度为0时,称为空表。
数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称,例如整形、浮点型、字符型这些就是数据类型。
我们对已有的数据类型进行抽象,就有了抽象数据类型(ADT),ADT是指一个数学模型及定义在该模型上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,与在计算机内如何实现是无关的。
描述抽象数据类型的伪代码格式:
ADT 抽象数据类型名
Data
数据元素之间逻辑关系的定义
Operation
操作
endADT
那么对于线性表List,可以这么描述:
ADT List
Data
a1,a2,a3,….an,每个元素的类型均为DataType,元素之间的关系一一对应。
Operation
InitList(*L); 初始化操作,建立一个空的线性表L;
ListEmpty(L); 判断是否为空表,返回bool;
ClearList(*L); 将线性表清空;
GetElem(L,i,*e); 将线性表L中第i个位置的元素返回给e;
LocateElem(L,e); 在线性表L中查找元素e,成功返回位置,失败返回0;
ListInsert(*L,i,e); 在线性表L中第i个位置插入新元素e;
ListDelete(*L, i, *e); 删除线性表L中第i个位置的元素,并用e返回其值;
ListLength(L); 返回线性表L的元素个数;
endADT
线性表只能有两种存储结构:顺序存储结构和链式存储结构。顺序存储指的是一段地址连续的存储单元依次存储线性表的数据元素,例如C++里的数组。
2、顺序存储结构
线性表顺序存储的结构代码如下:
#define MAXSIZE 20
Typedef int ElemType;
Typedef struct
{
ElemType data[MAXSIZE];
Int length; //线性表当前长度
}SqList;
实际中顺序存储相当于对数组进行了一个封装,顺序存储结构封装需要三个属性:
1、存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置;
2、线性表的最大存储容量,数组的长度MAXSIZE;
3、线性表当前长度length,会变化;
2.1、GetElem
GetElem:将线性表L中第i个元素值返回,注意其实返回的是i-1位置。
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
Typedef int Status; //Status是函数的类型,其值是函数结果状态
Status GetElem(SqList L, int i, ElemType *e)
{
If (L.length==0 || i<1 || i>L.length)
{
Return ERROR;
}
*e=L.data[i-1];
Return OK;
}
2.2、LinkInsert
ListInsert(*L, i ,e):在线性表L中的第i个位置插入新元素e。
Status ListInsert(SqList* L, int i, ElemType e)
{
int k;
if (L->length == MAXSIZE)
{
return false;
}
if (i<1 || i>L->length)
{
return false;
}
if (i <= L->length)
{
for (k = L->length - 1; k >= i - 1; k--)
//将要插入位置的后面的元素往后移1位
{
L->data[k + 1] = L->data[k];
}
}
L->data[i - 1] = e;
L->length++;
return true;
}
2.3、ListDelete
删除操作,ListDelete(*L, i, *e); 删除线性表L中第i个位置的元素,并用e返回其值。
Status ListDelete(SqList* L, int i, ElemType e)
{
if (L->length ==0 )
{
return false;
}
if (i<1 || i>L->length)
{
return false;
}
if (i < L->length)
{
for (int k = i; k < L->length; k++)
{
L->data[k - 1] = L->data[k];
}
}
L->length--;
return true;
}
插入和删除的时间复杂度:当插入和删除在最后一个位置操作,由于不需要移动任何元素,因此时间复杂度为O(1)。最坏的情况,对第一个位置进行操作,那么时间复杂度为O(n)。平均情况下为O((n-1)/2)=O(n)。因此线性表采用顺序存储结构时,读数据时的时间复杂度为O(1),插入和删除的时间复杂度为O(n)。这说明这个结构适合元素个数稳定的情况。此外,当线性表长度变化较大时,难以确定存储空间的容量。