1、第二章 线性表,2.1 线性表的定义和抽象数据类型,2.2 线性表的顺序存储结构,2.4 线性表的链式存储结构,第二章 线性表,2.3 线性表应用举例,2.5 线性表操作在单链表上的实现,第二章 线性表,2.1 线性表的定义和抽象数据类型,2.1.1 线性表的定义,2.1.2 线性表的抽象数据类型,2.1.3 操作举例,第二章 线性表,线性结构非线性结构顺序存储结构 链式存储结构 索引结构 散列结构,逻辑结构存储结构,数据结构,线性表 广义表 堆栈和队列 树 图,2.1.1 线性表的定义,A=( a1,a2,a3, . . , an ),(2) 除了第一个元素与最后一个元素,序列中任何一个元素
2、有且仅有一个直接前驱元素,有且仅有一个直 接后 继元素。,第二章 线性表,线性表(Linear List)是具有相同特性的数据元素的一个有限序列。,第二章 线性表,线性表的长度:表中元素的个数,用n表示空表:n=0 的线性表 线性表一般表示为: (a 1, a 2, , a i, a i+1, a n)a 1:表头元素;a n:表尾元素a i是第i个数据元素,i 是在表中的位序; 直接前驱元素是a i-1;直接后继元素a i+1 一个线性表可以用一个标识符来命名,如用A命名线性表,则:A=(a 1, a 2, , a i, a i+1, a n),第二章 线性表,二元组: linear_lis
3、t=(A,R) 元素类型ElemType是一种通用数据类型标识符,可以通过typedef语句在使用前将其定义为任一具体类型。如,整数 typedef typedef int ElemType ; 有序表:存在按值的升序或降序排列的字段(有序字段);不存在则为无序表,A = (a1,a2,a3, . . , an),数列: ( 25, 12, 78, 34, 100, 88),a1 a2 a3 a50,a1 a2 a3 a4 a5 a6,字母表: ( A, B, C, , X, Y, Z),a1 a2 a3 a24 a25 a26,数据文件:,第二章 线性表,2.1.2 线性表的抽象数据类型,由
4、一组数据结构和在该组数据结构上的一组操作所组成,抽象数据类型 (Abstract Data Type 简称ADT),第二章 线性表,数据部分:用标识符L表示一个线性表,可采用顺序、链接、散列等任一方式存储到计算机中,其存储类型用标识符ListType表示 操作部分:对线性表所作的各种操作运算,如插入、删除、求表的长度、判断表是否为空等,第二章 线性表,抽象数据类型线性表的定义如下:,ADT LinearList is,Data:,一个线性表L(a 1, a 2, , a i, a i+1, a n) 当L=( )时为空表,end LinearList,Operation:,操作描述请见后续页,
5、第二章 线性表,void InitList(ListType &L );,操作结果:,构造一个空的线性表 L。,初始化操作,第二章 线性表,清除操作,void ClearList(ListType &L );,操作结果:,清除线性表L中的所有元素, 使之成为一个空表。,第二章 线性表,int LenthList (ListType ,初始条件:操作结果:,线性表 L 已存在。,返回 L 中元素个数,若空则返回0。,求长度操作,第二章 线性表,bool EmptyList (ListType ,初始条件:操作结果:,线性表 L 已存在。,若 L 为空表,则返回 真(true),否则返回假(fal
6、se)。,线性表判空操作,第二章 线性表,ElemType GetList (ListType ,初始条件:操作结果:,线性表 L 已存在,,返回L中第pos个元素的值。 若pos出界,则打印出错信息,(求线性表中某个数据元素),且 1posLengthSize(L),第二章 线性表,void TraverseList (ListType ,初始条件:操作结果:,线性表 L 已存在。,按照 L 中元素的逻辑顺序访问每个元素,且每个元素仅被访问一次,(遍历线性表),第二章 线性表,bool FindList(ListType &L, ElemType& item);,初始条件:操作结果:,线性表
7、 L 已存在,item为给定值,查找 L 中值与item相等的元素 若成功返回真,由item返回该元素的值,否则返回假。,(查找函数),第二章 线性表,bool UpdateList (ListType &L, const ElemType& item);,初始条件:操作结果:,线性表 L 已存在,item为给定值,从L中查找值与item相等的元素 若成功则用item的值更新该元素的值,并返回真;否则返回假。,(更新函数),第二章 线性表,bool InsertList (ListType ,初始条件: 操作结果:,线性表 L 已存在,把item的值插入到L中第pos个位置, 若pos=-1,
8、则插入表尾。 插入操作后表L 的长度增1。,(插入数据元素),第二章 线性表,bool DeleteList (ListType ,初始条件: 操作结果:,线性表 L 已存在且非空,从L中删除满足某种条件的元素,若成功则返回true,否则返回false。 删除操作后表L 的长度减1。,(删除数据元素),第二章 线性表,排序操作,void SortList (ListType &L );,操作结果:,对L中的元素按值的升序重新排列,重排 后改变了元素之间的原有逻辑关系,按值 的升序建立了新的逻辑关系,第二章 线性表,2.1.3 操作举例,P50 e.g.线性表 L1=(25,38,19,42,3
9、3) , i=2, x=60, y=42 LenthList(L1) =5 EmptyList (L1) =false GetList (L1,i) =38 InsertList (L1,x,6) = (25,38,19,42,33,60) InsertList (L1,54,1) = (54,25,38,19,42,33,60) DeleteList (L1,y,0) = (54,25,38,19,33,60) DeleteList (L1,y,3) = (54,25,19,33,60) SortList (L1) = (19,25,33,54,60) InsertList (L1,35,0
10、) = (19,25,33,35,54,60),第二章 线性表,2.2 线性表的顺序存储和操作实现,2.2.1 线性表的顺序存储结构,2.2.2 顺序存储下的线性表操作的实现,2.2.3 线性表顺序存储空间的动态分配,2.2.1 线性表的顺序存储结构,若假设每个数据元素占用k个存储单元,并且已知第一个元素的存储位置LOC(a1),则有 LOC(ai) = LOC(a1)+(i-1)k,( a1,a2,a3, . . , an ),一. 构造原理,第二章 线性表,线性表的存储结构有顺序、链接、散列等多种方式 顺序存储结构是最简单、最常见的一种 设线性表的元素类型为ElemType,则每个元素所占
11、用存储空间大小为sizeof(ElemType),整个线性表所占用存储空间的大小为n*sizeof(ElemType),其中n为线性表的长度,第二章 线性表,线性表的顺序存储结构通常利用数组来实现 设用具有ElemType类型的数组listMaxSize存储线性表A(a 1, a 2, , a i, a i+1, a n),且起始存储位置为 list,则第 i 个元素的存储位置为:list + (i-1)* sizeof (ElemType) 数组 list 的下标的上界MaxSize决定了线性表的最大长度,第二章 线性表,用一组地址连续的存储单元依次存放线性表中的数据元素,0 1 i-1 i
12、 n-1 ,线性表的起始地址, 称作线性表的基地址,a1 a2 ai ai+1 an ,MaxSize-1,在程序设计语言中,一维数组的表示:,Pascal 语言: A1nA1, A2, Ai, An,C 语言: AnA0, A1, Ai, An-1,Fortran 语言: AnA1, A2, Ai, An,线性表的顺序存储结构的特点,1. 优点:,2. 缺点:,(1) 构造原理简单、直观,易理解。,(2) 元素的存储地址可以通过一个简单的解析式计算出来。,(1) 存储分配需要事先进行。,(2) 需要一片地址连续的存储空间。,(3) 基本操作(如插入删除)的时间效率较低。,第二章 线性表,顺序
13、存储结构的程序设计语言描述:,struct List ;,ElemType listMaxsize; / 存储数组/Maxsize为常量整数,int size; / 存储线性表的长度,第二章 线性表,/动态存储 struct List int MaxSize; ;,ElemType *list;,int size;,第二章 线性表,2.2.2 顺序存储下的 线性表操作的实现,1、初始化线性表:动态分配空间,置为空表 void InitList (List /置为空表 ,第二章 线性表,2、删除线性表中所有元素 即:只需将其长度置为0 void ClearList (List ,第二章 线性表,
14、3、得到线性表的长度 即:返回线性表L的size域的值 int LenthList (List ,第二章 线性表,4、检查线性表是否为空 即:判断其长度是否为0,“是”返回true,“否”返回falsebool EmptyList (List ,第二章 线性表,5、得到线性表中指定序号的元素 即:使用L.listpos-1从L中取出第pos个元素 ElemType GetList (List ,第二章 线性表,6、遍历线性表 即:依次访问L中list0-listn-1的每一个元素 void TraveseList (List ,第二章 线性表,7、从线性表中查找具有给定值的第一个元素 即:找到
15、 i,使得item = L.listi,则由item返回该元素的整体值,且该函数返回 1 bool FindList (List ,第二章 线性表,8、更新线性表中具有给定值的第一个元素 即:找到 i,使得item = L.listi,则用item的值修改该元素的值,且该函数返回 true bool UpdateList (List ,第二章 线性表,(7)(8)的算法中,运行时间主要取决于比较元素的次数 最好:第一个元素list0等于待查找或待更新的元素,则仅此一次就结束操作,对应的时间复杂度为O(1) 最坏:最后一个元素listn-1等于待查找或待更新的元素,则需n次比较才结束操作,对应的
16、时间复杂度为O(n),第二章 线性表,平均:当元素值互不相同,且以平均概率1/n等于待查找或待更新的元素时,则需要比较元素的平均次数为所以平均情况下对应的时间复杂度为O(n) 若查找失败,即依次同线性表中所有 n 个元素比较后仍找不到与给定值相等的元素,则算法执行return false 语句后结束,其时间复杂度为O(n) 小结:无论查找成功或失败,顺序查找线性表的时间复杂度均为O(n),第二章 线性表,9、向线性表中按给定条件插入一个元素 当pos=0时,将元素item加到有序表的恰当位置,使其插入后仍然有序。用顺序查找法确定插入的恰当位置。 A= (25,36,40,48,55,72,83
17、) 插入16,则(16,25,36,40,48,55,72,83) 插入50,则(25,36,40,48,50,55,72,83) 插入92,则(25,36,40,48,55,72,83,92),第二章 线性表,9、向线性表按给定条件插入一个元素 当pos=-1时,把 item插入到线性表的表尾 当1=pos-1; i-)L.listi+1 = L.listi;L.listpos-1 = item;L.size + ; ,第二章 线性表,10、从线性表中删除符合给定条件的第一个元素同插入算法类似Bool DeleteList(List if (pos =0),第二章 线性表,10、从线性表中删除等于给定值的第一个元素for (int i=0; iL.size; i+)if (L.listi= =item) break;if (i= =L.size)cout “被删除元素不存在!”endl; return false;pos = i+1;else if (pos = -1) pos = L.size;item = L.listpos-1; for (i=pos; iL.size; i+)L.listi-1 = L.listi; L.size - ;return true; ,