数据结构和算法中更是生活中最常用的结构:线性表
线性表的基本概念
线性表的定义
线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。数据元素是一个抽象的符号,其具体含义在不同的情况下一般不同。
在稍复杂的线性表中,一个数据元素可由多个数据项(item)组成,此种情况下常把数据元素称为记录(record),含有大量记录的线性表又称文件(file)。
线性表中的个数n定义为线性表的长度,n=0时称为空表。在非空表中每个数据元素都有一个确定的位置,如用ai表示数据元素,则i称为数据元素ai在线性表中的位序。
线性表的相邻元素之间存在着序偶关系。如用(a1,…,ai-1,ai,ai+1,…,an)表示一个顺序表,则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1,2,…,n-1时,ai有且仅有一个直接后继,当i=2,3,…,n时,ai有且仅有一个直接前驱。
线性表的特点
- 数据元素之间具有一种线性的或“一对一”的逻辑关系。
- 第一个数据元素没有前驱,这个数据元素被称为开始节点;
- 最后一个数据元素没有后继,这个数据元素被称为终端节点;
- 除了第一个和最后一个数据元素外,其他数据元素有且仅有一个前驱和一个后继
线性表的抽象数据类型
线性表的抽象数类型定义
ADT 线性表
Data :
线性表的数据对象集合为{
a1,a2,......,an},每个元素的类型均为DataType。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
Operation:
InitList(*L)
操作结果:构造一个空的线性表L
ClearList(*l)
初始条件:线性表已存在
操作结果:置线性表L为空表
ListEmpty(L)
初始条件:线性表已存在
操作结果:若线性表L为空表,则返回TRUE,否则返回FALSE
ListLenght(L)
初始条件:线性表已存在
操作结果:返回线性表L数据元素个数
GetElem(L,i,*e)
初始条件:线性表已存在(1≤i≤ListLenght(L))
操作结果:用e返回线性表L中第i个数据元素的值
LocateElem(L,e)
初始条件:线性表已存在
操作结果:在线性表L种查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号;否则返回0
ListInsert(*L,i,e)
初始条件:线性表已存在(1≤i≤ListLenght(L)+1)
操作结果:在线性表L中第i个数据元素之前插入新元素e,L长度加1
ListDelete(*L,i,*e)
初始条件:线性表已存在(1≤i≤ListLenght(L))
操作结果:删除线性表L中第i个数据元素,用e返回其值,线性表L长度减1
endADT
实现两个线性表A和B的并集操作
void unionL(List *La,List *Lb)
{
int La_len,Lb_len,i;
ElemType e;
La_len = ListLength(*La);
Lb_len = ListLength(*Lb);
for (i=1;i<=Lb_len;i++)
{
GetElem(Lb,i,&e);/*取Lb中第i个数据元素赋给e* */
if (!LocateElem(*La,e))/*La中不存在和e相同数据元素*/
ListInsert(La,++La_len,e);/*插入*/
}
}
线性表的顺序存储结构
顺序存储结构相关定义
线性表的顺序存储结构指的是用一组连续的存储单元一次存储线性表中的各个元素,使得线性表中在逻辑上相连的元素存储在连续的物理存储单元上。通过数据元素物理存储的连续性来反映数据元素在逻辑上的相邻关系。采用顺序存储结构的线性表通常叫做顺序表
顺序存储方式
各种语言都一般采用一维数组实现
#define MAXSIZE 20 /*存储空间初始分配量*/
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];/*数组存储数据元素,最大值为MAXSIZE*/
int length;/*线性表当前长度*/
}SqList
数据长度和线性表长度区别
数组的长度是不变的
线性表的长度是可变的
地址计算
数组和线性表长度区别是,数组一般是0,1,2,线性表一般是a1,a2,a3…
简单说,数组从0开始,线性表从1开始
假设一个数据元素占用c个存储单元,LOC表示Location
则有公式 LOC(ai)=LOC(a)+(i-1)*c
通过这个公式可知,计算顺序表任意位置的地址的时间都相同,那么可知对于计算机,存取顺序表数据都是O(1),通常把具有这一特点的存储结构称为随机存取结构
顺序存储结构的基本操作
取元素操作
GetElem:将顺序表L中第i个位置元素返回,即返回数组的i-1下标的值
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
/*Status是函数的类型,值是函数结果状态*/
/*初始条件:顺序表L存在,且不为空表*/
/*操作结果:e返回L中第i个数据元素的值*/
Status GetElem(SqList L,int i,ElemType *e)
{
if (L.length==0 || i < 1 || i >L.length)
return ERROR;
*e = L.data[i-a];
return OK;
}
插入元素操作
插入操作实现思路,假设插入位置为i
- 插入位置不合理,抛出异常
- 顺序表长度大于数组长度,抛出异常或动态增长数组
- 从最后一个元素向前遍历到第i个位置,分别将他们向后移动一个位置
- 将要插入元素填入位置i处
- 顺序表表长增加1
实现代码
/*始条件:顺序表L已存在,且i位置存在*/
/*操作结果:在L中i位置之前插入新的数据元素e,L长度+1*/
Status ListInsert