1.线性表的定义和特点
- 线性表是具有相同特性的数据元素的一个有限序列
线性表:由n(n>=0)个数据元素(结点)a1,a2,…an组成的有限序列。
-
其中数据元素的个数n定义为表的长度
-
当n=0时称为空表
-
将非空的线性表(n>0)记作:(a1,a2,…an)
-
这里的数据元素ai(1<=i<=n)只是一个抽象的符号,其具体含义在不同的情况下可以不同
-
开始结点没有直接前趋,终端结点没有直接后继,其余结点都有一个直接前趋和一个直接后继
同一线性表中的元素必定具有相同特性,数据元素间的关系是线性关系,线性表是典型的线性结构
2.线性表的运算
2.1案例
稀疏多项式的运算:
求两个多项式的和时,除了直接将多项式相加,还可以将它们的线性表相加,以上图的线性表A和B为例:
-
创建一个新数组C
-
分别从头遍历比较A和B的每一项
- 指数相同,对应系数相加,若其和不为零,则在C中增加一个新项
- 指数不相同,则将指数较小的项复制到C中
-
一个多项式已遍历完毕时,将另一个剩余项依次复制到C中即可
结果为:
项数 | 第一项 | 第二项 | 第三项 | 第四项 |
---|---|---|---|---|
指数 | 0 | 1 | 7 | 17 |
系数 | 7 | 11 | 22 | 5 |
用线性表表示:C=(7,0),(11,1),(22,7),(5,17)
用多项式表示:C(X)=7+11x+22x7+5x17
2.2小结
- 线性表中数据元素的类型可以为简单类型,也可以为复杂类型。
- 许多实际应用问题涉及的基本操作有很大相似性,不需要为每个应用单独编写新的程序。
- 从具体应用中抽象出共性的逻辑结构和基本操作(抽象数据类型),然后实现其存储结构和基本操作。
3.线性表的基本操作
-
InitList(&L)
- 操作结果:构造一个空的线性表L
-
DestoryList(&L)
- 初始条件:线性表L已存在
- 操作结果:销毁线性表L
-
ClearList(&L)
- 初始条件:线性表L已存在
- 操作结果:将线性表L重置为空表
-
ListEmpty(L)
- 初始条件:线性表L已存在
- 操作结果:若线性表L为空表,则返回TRUE,否则返回FALSE。
-
ListLength(L)
- 初始条件:线性表L已存在
- 操作结果:返回线性表L中的数据元素个数
-
GetElem(L,i,&e)
- 初始条件:线性表L已存在,1<=i<=ListLength(L)。
- 操作结果:用e返回线性表L中第i个数据元素的值
-
LocateElem(L,e,compare())
- 初始条件:线性表L已存在,compare()是数据元素判定函数(>,<,=等)。
- 操作结果:返回L中第一个与e满足compare()的数据元素的位序。若这样的数据元素不存在则返回值为0。
-
PriorElem(L,cur_e,&pre_e)
- 初始条件:线性表L已存在
- 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前趋,否则操作失败,pre_e无意义。
-
NextElem(L,cur_e,&next_e)
- 初始条件:线性表L已存在
- 操作结果:若cur_e是L的数据元素,且不是第一个,则用next_e返回它的后继,否则操作失败,next_e无意义。
-
ListInsert(&L,i,e)
-
初始条件:线性表L已存在,1<=i<=ListLength(L)+1。
-
操作结果:在L的第i个位置之前插入新的数据元素e,L的长度加一。
-
插入元素e之前(长度为n):(a1,a2,…,ai-1,ai,…,an)
-
插入元素e之后(长度为n+1):(a1,a2,…,ai-1,e,ai,…,an)
-
-
ListDelete(&L,i,&e)
- 初始条件:线性表L已存在,1<=i<=ListLength(L)。
- 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减一。
- 删除前(长度为n):(a1,a2,…,ai-1,ai,ai+1,…,an)
- 删除后(长度为n-1):(a1,a2,…,ai-1,ai+1,…,an)
-
ListTraverse(&L,visted())
- 初始条件:线性表L已存在
- 操作结果:依次对线性表中每个元素调用visited()
4.线性表的顺序表示(即顺序表)
线性表的顺序表示又称为顺序存储结构或顺序镜像。
顺序存储:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构,用这种方式存储的线性表又叫顺序表。逻辑上相邻,物理上也相邻。
线性表的第一个数据元素a1的存储位置,称作线性表的起始位置或基地址。
-
依次存储,地址连续,中间没有空出存储单元是一个典型的线性表顺序存储结构。
-
地址不连续,中间存在空的存储单元不是一个线性表顺序存储结构。
-
线性表顺序存储结构占用一片连续的存储空间。知道某个元素的存储位置就能计算其他元素的存储位置。
顺序表的特点:以物理位置相邻表示逻辑关系;任一元素均可随机存取。
定义线性表的模板:
SqList(Sequence List):顺序表
多项式转为线性表:
5.顺序表的相关操作
定义顺序表:
线性表L的初始化(参数用的引用类型):
销毁线性表L:
清空线性表L:
顺序表的取值(根据位置i获取相应位置数据元素的内容):
顺序表的查找:
- 在线性表L中查找与指定值e相同的数据元素的位置
- 从表的一端开始,逐个进行记录的关键字和给定值的比较。如果找到,返回该元素的位置序号,如果未找到,返回0。
平均查找长度ASL:为确定记录在表中的位置,需要与给定值进行比较的关键字的个数的期望值叫做查找算法的平均查找长度。
顺序表的插入(以插入一个元素为例):
- 插入位置在最后:直接将元素放在顺序表最后一个元素之后(耗时最短)。
- 插入位置在中间:将插入位置原本的元素和其后的元素全部往后移动一位,再将元素插入其中。
- 插入位置在最前:将所有元素向后移动一位,再将元素放在第一位(耗时最长)。
线性表的插入运算是指在表的第i(1<=i<=n+1)个位置上,插入一个新结点e,使长度为n的线性表(a1,…,ai-1,ai,…,an)变成长度为n+1的线性表(a1,…,ai-1,e,ai,…,an);如果顺序表存储空间已满,则返回ERROR,插入失败;插入成功后表长+1。
插入操作代码:
顺序表插入算法的平均时间复杂度为O(n),空间复杂度为O(1)。
顺序表的删除(以插入一个元素为例):
- 删除位置在最后:直接删除最后一个元素,数组长度减一(操作速度快)。
- 删除位置在中间:删除后将其后面的所有元素向前移一位,数组长度减一。
- 删除位置在最前:删除后将所有元素向前移一位,数组长度减一(操作速度慢)。
线性表的删除运算是指将表的第i(1<=i<=n)个结点删除使长度为n的线性表(a1,…,ai-1,ai,ai+1,…,an)变成长度为n-1的线性表(a1,…,ai-1,ai+1,…,an),删除成功返回OK。
删除操作代码:
顺序表删除算法的平均时间复杂度为O(n),空间复杂度为O(1)。
6.小结
顺序表(线性表的顺序存储结构)的特点:
- 利用数据元素的存储位置表示线性表中相邻元素之间的前后关系,即线性表的逻辑结构与存储结构一致。
- 在访问线性表时,可以快速的计算出热河一个数据元素的存储地址。因此可以粗略的认为,访问每个元素所花时间相等。
- 这种存取数据的方法称为随机存取法
顺序表的优缺点:
优点:
-
存储密度大(结点本身所占存储量/结点结构所占存储量=1)
-
可以随机存取表中任一元素
缺点:
- 在插入,删除某一元素时,需要移动大量元素
- 浪费存储空间
- 属于静态存储方式,数据元素的个数不能自由扩充