线性表的类型定义
作者:互联网
线性表(linear_list)是最常用且最简单的一种数据结构。简言之,一个线性表是n个数据元素的有限 序列。至于每个数据元素的具体含义,在不同的情况下各不相同,它可以是一个数一个符号,也可以是一页书,甚至是其他更复杂的信息。例如,26个英文字母表是一个线性表,表中的数据元素是单个字母字符。
(A,B,C,...,Z)
又如,某小学从2000年到2020年拥有的计算机数的变化情况,可以用线性表的形式给出,表中的数据元素是整数
(6,12,23,34,45,...,99)
在稍复杂的线性表中,一个数据元素可以由若干个数据项(item)组成。在这样情况下,常把数据元素称为记录,含有大量记录的线性表又称文件
例如,一个学校的学生返校健康情况等级表,表中每个学生的情况为一个记录,它由姓名、学号、性别、年龄、班级和健康状况这6个数据项组成。
综上所述,线性表中的数据元素可以是各种各样的,但同一线性表中的元素必定具有相同特性,即属同一数据对象,相邻数据元素之间存在着序偶关系。若将线性表记为
则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1,2,···,n-1时,ai有且只有一个直接后继,当i=2,3,···,n时,ai有且仅有一个直接前驱。
注意:除第一个之外,集合中的每个数据元素均只有一个前驱;
除最后一个之外,集合中每个数据元素均只有一个后继;
线性表中元素的个数n(n>=0)定义为线性表的长度,n=0时称为空表。在非空表中的每个元素都有一个确定的位置,如a1是第一个数据元素,an是最后一个数据元素,ai是第i个数据元素,称i为数据元素ai在线性表中的位序
线性表是一个相当灵活的数据结构,它的长度可根据需要增长或缩短,即对线性表的抽象元素不仅可以访问,还可以进行插入和删除等。
ADT List {
数据对象:D={ | ∈ ElemSet, i=1,2,...,n, n≥0 }
数据关系:R1={ <ai-1 ,ai >| ,∈D, i=2,...,n }
基本操作:
{结构初始化}
InitList( &L )
操作结果:构造一个空的线性表 L 。
{销毁结构}
DestroyList( &L )
初始条件:线性表 L 已存在。
操作结果:销毁线性表 L 。
例如,26个小写英文字母是一个线性表
(a,b,…,z)
同一花色的13张扑克牌
(2,3,4,5,6,7,8,9,10,J,Q,K,A)
可以构成一个线性表。
序偶 <,> 表示 是 的直接前驱,反之, 是 的直接后继。
{引用型操作}
ListEmpty( L )
初始条件:线性表L已存在。
操作结果:若 L 为空表,则返回 TRUE,否则返回 FALSE。
ListLength( L )
初始条件:线性表 L 已存在。
操作结果:返回 L 中元素个数。
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 无定义。
GetElem( L, i, &e )
初始条件:线性表 L 已存在,1≤i≤LengthList(L)。
操作结果:用 e 返回 L 中第 i 个元素的值。
LocateElem( L, e, compare( ) )
初始条件:线性表 L 已存在,compare( ) 是元素判定函数。
操作结果:返回 L 中第1个与 e 满足关系 compare( ) 的元素的位序。
若这样的元素不存在,则返回值为0。
ListTraverse(L, visit( ))
初始条件:线性表 L 已存在,visit( ) 为元素的访问函数。
操作结果:依次对 L 的每个元素调用函数 visit( )。
一旦 visit( ) 失败,则操作失败。
{加工型操作}
ClearList( &L )
初始条件:线性表 L 已存在。
操作结果:将 L 重置为空表。
PutElem( &L, i, &e )
初始条件:线性表L已存在,1≤i≤LengthList(L)。
操作结果:L 中第 i 个元素赋值同 e 的值。
ListInsert( &L, i, e )
初始条件:线性表 L 已存在,1≤i≤LengthList(L)+1。
操作结果:在 L 的第 i 个元素之前插入新的元素 e,L 的长度增1。
ListDelete( &L, i, &e )
初始条件:线性表 L 已存在且非空,1≤i≤LengthList(L)。
操作结果:删除 L 的第 i 个元素,并用 e 返回其值,L 的长度减1。
} ADT List
具体可参考https://blog.csdn.net/m57091003/article/details/1911982
对于上述定义的抽象数据类型线性表,还可进行一些更复杂的操作,例如,将两个或多个以上的线性表合并成一个线性表;把一个线性表拆开成两个或两个以上的线性表;重新复制一个线性表等。
例:
假设利用两个线性表LA和LB分别表示两个集合A和B(即线性表中的数据元素即为集合中的成员),
现要求一个新的集合A = A U B。这就要求对线性表做如下操作:
扩大线性表LA,将存在于线性表LB中依次取得每个数据元素,并依次在线性表LA中进行查看,若不存在,则插入。
void union(List &La, List Lb){
//将所有在线性表Lb但不在La中的数据元素插入到La中
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,equal)
ListInsert(La,++La_len,e);
//La中不存在和e相同数据元素,则插入
}
}//union
例:
已知线性表LA和LB中国的数据元素按值递增有序排列,现要求将LA和LB归并为一个新的线性表LC,
且LC中的数据元素仍按值递增排列。
LA = (3,5,8,11)
LB = (2,6,8,9,11,25,20)
则
LC = (2,3,5,6,8,8,9,11,11,15,20)
从上述要求可知,LC中的数据元素或是LA中的数据元素,或是LB中的数据元素,则只要先设LC为空表,然后将LA或LB中的元素逐个插入LC中。为使LC中元素按值递增排列,可设两个指针i和j分别指向LA和LB中某个元素,若设i当前所指的元素为a,j当前所指的元素为b,则当前应插入LC中的元素c为
void MegeList(List La, List Lb, List &Lc){
//已知线性表La和Lb中的数据元素按值递增排列
//Lc也呈递增排雷
InitList(Lc);
i = j =1;
k = 0;
La_len = ListLength(La);
Lb_len = ListLength(Lb);
while( (i<=La_len) && Lb_len = ListLength(Lb) ){ //La和Lb均非空
GetElem(La, i, ai);
GetElem(Lb, j, bi);
if(ai <= bj){
ListInsert(Lc, ++k, ai);
++i;}
else{
ListInsert(Lc,++k,bj);
++j;}
}
while(i <= La_len){
GetElem(La, i++, ai);
ListInsert(Lc, ++k, ai);
}
while(j <= Lb_len){
GetElem(Lb, j++, bj);
ListInsert(Lc, ++k, bi);
}
}
上述两个算法的时间复杂度取决于抽象数据类型List定义中基本操作的执行时间。假设GetElem和ListInsert这两个操作的执行时间和表长无关,LocateElem的执行时间和表长成正比,则前一个算法的时间复制度为O(ListLength(LA) * ListLength(LB)),第二个算法的时间复杂度则为O(ListLength(LA) + ListLength(LB))。后面一个算法虽然有三个while循环语句,但只有当i和j均指向表中实际存在的数据元素时,才能取得数据元素的值并进行比较;并且当其中一个线性表的数据元素均已插入线性表LC中后,只要将另外一个线性表中的剩余元素依次插入即可。因此,对于每一组具体的输入(LA和LB),后两个while循环语句只执行一个循环体。
标签:LB,线性表,LA,ai,元素,类型定义,数据 来源: https://blog.51cto.com/u_15249901/2865691