第3章 顺序存储结构的表、堆栈和队列.ppt
《第3章 顺序存储结构的表、堆栈和队列.ppt》由会员分享,可在线阅读,更多相关《第3章 顺序存储结构的表、堆栈和队列.ppt(127页珍藏版)》请在课桌文档上搜索。
1、第3章 顺序存储结构的表、堆栈和队列,3.1 顺序存储结构3.2 表和顺序表 3.3 堆栈和顺序堆栈3.4 队列和顺序队列3.5 优先级队列和顺序优先级队列,3.1 顺序存储结构,计算机所处理的所有的数据都要存储在内存中。计算机高级语言系统对数据的存储结构有四种:顺序存储结构、链式存储结构、间接地址和仿真指针。其中,顺序存储结构和链式存储结构是两种最基本和最常用的存储结构。本节讨论顺序存储结构,其余三种存储结构依次在4.1节、5.2节和7.1节中讨论。,顺序存储结构是计算机中的一种最基本和最主要的数据存储结构。在顺序存储结构中,用户向系统申请一块地址连续的有限空间用于存储数据元素集合,这样,任
2、意两个在逻辑上相邻的数据元素在物理上也必然相邻。在C+中,向系统申请一块地址连续的有限空间的方法是使用数组。数组有静态数组和动态数组两种。不论是静态数组还是动态数组,其功能都是向系统申请一块地址连续的有限空间,只是使用的方法不同。,C+中静态数组向系统申请一块地址连续的有限空间的方法是使用数组定义语句“”。当程序运行超出该静态数组定义的范围时,系统自动回收该静态数组的地址空间。一个静态数组定义的例子如下:include const int MaxSize=100;void main(void)int i;int tempMaxSize;/静态申请MaxSize个整型元素的存储空间,for(i=
3、0;i6;i+)tempi=i+1;printf(temp%d=%dn,i,tempi);/C函数输出,当程序运行退出主函数时,系统将自动回收分配给静态数组temp的地址空间。C+中动态数组向系统申请一块地址连续的有限空间的方法是使用动态存储分配函数。动态数组存储空间的回收方法是当不再需要该动态数组时,使用动态存储释放函数。C+中动态存储分配函数用new,动态存储释放函数用delete。new能自动计算要分配类型的空间大小并自动返回正确的指针类型。delete能自动释放由new分配的存储空间。,new的语法格式是:名字指针=new类型名(初始化值)。其中,初始化值可为空。new分配动态数组的语
4、法格式是:名字指针=new类型名N。其中,N必须是有确定值的整数型常量或变量。delete的语法格式是:delete名字指针 delete释放动态数组的语法格式是:delete名字指针上例的动态数组定义的例子如下:,include include void main(void)int i,*temp;const int MaxSize=100;temp=new intMaxSize;/动态申请MaxSize个整型元素的存储空间,for(i=0;i6;i+)tempi=i+1;/动态数组测试 couti=itempi=tempiendl;delete temp;/释放申请的动态存储空间,从上例可
5、见,静态数组存储空间的申请和释放由系统自动完成,动态数组存储空间的申请和释放由用户通过调用系统函数完成。设要存储的数据元素为a0,a1,a2,a3,a4,a5,顺序存储结构(不论是用静态数组还是用动态数组)向系统申请了MaxSize个ai数据类型的存储空间,size为数组的当前数组元素个数。其内存结构示意图如图31所示。,图31 顺序存储结构内存结构示意图,3.2 表和顺序表,表(List)是一种可在任意位置进行插入和删除操作的由n(n0)个相同类型数据元素组成的线性结构,n是表的长度,n=0的表称作空表。从数据元素之间的逻辑关系来划分,数据结构可分为线性结构和非线性结构两种。线性结构是指数据
6、元素之间的逻辑关系为除第一个元素和最后一个元素外,每个数据元素都只有一个前驱元素和一个后继元素。表是最简单的一种线性结构。,对表的操作方法主要有初始化构造表、在表的某一位置插入一个元素、在表的某一位置删除一个元素、定位某个数据元素在表中的存储位置、取表中某个存储位置的数据元素、判表是否为空等。用顺序存储结构存储的表称作顺序表(SequentList)。顺序表中任意数据元素的存取和访问可通过它的位置指针(即数组下标)来进行。,3.2.1 顺序表的类定义 综合前面的讨论可知,一个顺序表涉及的数据成员包括数组、数组的最大元素个数和当前数组元素的个数。顺序表的操作方法和前面讨论的表的操作方法相同,主要
7、有初始化构造表、在表的某一位置插入一个元素、在表的某一位置删除一个元素、定位某个数据元素在表中的存储位置、取表中某个存储位置的数据元素、判表是否为空等。使用静态数组方法的顺序表的类定义如下:,includeincludeconst int MaxListSize=100;MaxListSize是问题要求的元素数目的最大值Class SeqList private:Datatype dataMaxListSize;/抽象类型Datatype定义的数组 int size;/数据元素个数,public:SeqList(void);/构造函数 SeqList(void);/析构函数 int ListS
8、ize(void)const;/返回元素的个数size int ListEmpty(void)const;/表空返回1;否则返回0 int Find(Datatype,3.2.2 顺序表的类实现顺序表类SeqList的实现如下:/构造函数。置顺序表的数据元素个数size为0SeqList:SeqList(void):size(0)/析构函数SeqList:SeqList(void)/返回顺序表的数据元素个数sizeintSeqList:ListSize(void)const return size;,/判顺序表空否,为空返回1;不空返回0intSeq List:ListEmpty(void)c
9、onst if(size=0)return1;elseKG*4return0;/定位元素item的位置,返回值为item在顺序表中的位置;返回值为-1表示不存在intSeq List:Find(Datatype&item)const,if(size=0)return-1;inti=0;while(isize-1)/取的元素序号必须在0至size-1之间,cerr参数pos越界出错!endl;exit(1);/参数1表示出错退出 returndatapos;/在指定位置pos插入一个数据元素itemvoidSeqList:Insert(constDatatype,if(possize)/当pos
10、等于size时表示插入在最后 cerrpos;i-)datai=datai-1;datapos=item;/在pos位置插入item size+;/数据元素个数size加1,/删除指定位置pos上的数据元素并返回DatatypeSeqList:Delete(constintpos)if(size=0)cerrsize-1)/删除元素序号必须在0至size-1之间 cerr参数pos越界出错!endl;exit(1);,Datatypetemp=datapos;/从pos至size-2逐个元素左移,datasize-1移入datasize-2中 for(inti=pos;isize-1;i+)d
11、atai=datai+1;size-;/数据元素个数size减1 returntemp;/置顺序表为空voidSeqList:ClearList(void)size=0;/数据元素个数size置为初始化值,3.2.3 顺序表上插入、删除算法的效率分析 顺序表上的插入和删除是顺序表类中时间复杂度最高的成员函数。顺序表上的插入和删除过程的图示如图32(a)和图32(b)。图32(a)是在原来已有6个元素的顺序表的pos=3位置插入数据元素item=13的过程图示;图32(b)是在原来已有7个元素的顺序表中删除pos=3位置的数据元素的过程图示。,图32 顺序表上的插入和删除(a)插入一个数据元素;
12、(b)删除一个数据元素,在顺序表中插入一个数据元素时,算法中时间复杂度最高的部分是循环移动数据元素。循环移动数据元素的效率和插入数据元素的位置pos有关,最坏情况是pos=0,需移动size个数据元素;最好情况是pos=size,需移动0个数据元素。设Pi是在第i个存储位置插入一个数据元素的概率,设顺序表中的数据元素个数为n,当在顺序表的任何位置上插入数据元素的概率相等时,有Pi=1(n+1),则向顺序表插入一个数据元素时所需移动的数据元素的平均次数为,在顺序表中删除一个数据元素时,算法中时间复杂度最高的部分也是循环移动数据元素。循环移动数据元素的效率和删除数据元素的位置pos有关,最坏情况是
13、pos=0,需移动size-1个数据元素;最好情况是pos=size,需移动0个数据元素。设Qi是在第i个存储位置插入一个数据元素的概率,设顺序表中已有的数据元素个数为n,当在顺序表的任何位置上插入数据元素的概率相等时,有Qi=1/n,则向顺序表插入一个数据元素时所需移动的数据元素的平均次数为:,在顺序表中定位一个数据元素时,累加计数变量i次数的分析和在顺序表中删除一个数据元素的分析类同。顺序表中的其余操作都和数据元素个数n无关,因此,在上述顺序表中插入和删除一个数据元素的时间复杂度为O(n);定位一个数据元素的时间复杂度为O(n);其余操作的时间复杂度均为O(1)。,在进行面向对象的程序设计
14、时,任何一个新类的设计都要考虑它的派生类对它的继承。当把顺序表上的插入和删除成员函数设计成如图33所示的方式时,任何类似顺序表但对顺序表上插入和删除操作要考虑数据元素原来顺序的都不能继承它。解决这个问题的一个方法是设计一个顺序表基类,然后分别设计两个派生类,一个设计成图32方式的插入和删除成员函数,另一个设计成图33方式的插入和删除成员函数。这样上述问题就可妥善解决。,图33 顺序表上不考虑原来顺序的插入和删除(a)插入一个数据元素;(b)删除一个数据元素,3.2.4 顺序表的应用 例31 编写一个程序向顺序表中插入5个整数值,然后以插入次序删除这5个数。程序如下:typedefintData
15、type;具体应用时定义的数据类型DatatypeincludeSeqList.h“类SeqList的定义和实现头文件voidmain(void)SeqListmyList;for(inti=0;i5;i+)插入5个整型元素,myList.Instert(i+10,i);cout测试GetData()成员函数结果如下:endl;for(i=0;i5;i+)coutmyList.GetData(i);cout测试Delete()成员函数结果如下:endl;for(i=0;i5;i+)coutmyList.Delete(0);,程序输出为:测试GetData()成员函数结果如下:10 11 12
16、13 14测试Delete()成员函数结果如下:10 11 12 13 14,在上述顺序表类SeqList的定义中,数据类型Datatype是一个未定义的抽象符号。在上面我们定义数据类型Datatype为整型int,我们也可以定义数据类型Datatype为字符型char,我们还可以定义数据类型Datatype为任意一个自定义的结构体类型或一个类类型。定义数据类型Datatype为一个自定义的结构体类型的例子见本章例33;定义数据类型Datatype为一个类类型的概念见2.2节中类Line中对类Point类型变量的定义。下面是例31数据类型Datatype改为char类型的程序。,typedef
17、charDatatype;/定义数据类型Datatype为char类型includeSeqList.hvoidmain(void)SeqListlist;inti;,for(i=0;i5;i+)/插入5个字符元素 list.Insert(A+i,i);for(i=0;i5;i+)/依次删除5个字符元素并在屏幕显示 coutlist.Delete(0)“;此时程序的输出为:A B C D E,3.3 堆栈和顺序堆栈,堆栈(Stack)是一种特殊的线性表,是一种只允许在表的一端进行插入和删除操作的线性表。堆栈中允许进行插入和删除操作的一端称为栈顶,另一端称为栈底。栈顶的当前位置是动态的,标识栈顶当
18、前位置的称为栈顶指示器(或栈顶指针)。堆栈的插入和删除操作通常称为进栈或入栈,堆栈的删除操作通常称为出栈或退栈。当栈中没有数据元素时称之为空栈。,根据堆栈的定义,每次进栈的数据元素都放在原当前栈顶元素之前而成为新的栈顶元素,每次退栈的数据元素都是原当前栈顶元素,这样,最后进入堆栈的数据元素总是最先退出堆栈,因此,堆栈也称作后进先出表。用顺序存储结构存储的堆栈称为顺序堆栈(SequentStack)。图34是一个顺序堆栈的动态示意图。图中,最大元素个数设为6,top为栈顶指示器。图34(a)表示一个空栈;图34(b)表示插入一个数据元素A后的状态;图34(c)表示插入数据元素B、C、D后的状态;
19、图34(d)表示删除数据元素D、C后的状态;图34(e)表示删除数据元素B、A后的状态。,图34 顺序堆栈的动态示意图(a)空栈;(b)插入数据元素A后;(c)插入数据元素B、C、D后;(d)删除数据元素D、C后;(e)删除数据元素B、A后,3.3.1 顺序堆栈类定义和实现 1.直接类定义和实现方法 直接定义是指直接定义顺序堆栈类,不考虑顺序堆栈类数据成员对顺序表类数据成员的继承。下面的顺序堆栈定义中部分类成员函数使用了内联函数的方法。include include cons tint MaxStackSize=100;class SeqStack,private:DatatypedataMa
20、xStackSize;/抽象类型Datatype的数组 inttop;/栈顶位置指示器 public:SeqStack(void)/构造函数 top=0;/内联函数方式 SeqStack(void)/析构函数;/内联函数方式,voidPush(constDatatype,栈顶位置指示器top和顺序表中的当前元素个数size的含义完全相同,只是在堆栈中用top更能反映它的栈顶位置指示器的含义,所以在此使用了不同的名字。此外,顺序堆栈中的数组data和顺序表中的数组data也完全相同。因此我们说,顺序堆栈和顺序表的逻辑结构完全相同,只是两者允许的操作集合不同,顺序表允许在任意位置插入和删除,而顺序
21、堆栈只允许在栈顶位置插入和删除,所以我们也可以说,顺序堆栈是操作受限制的顺序表。,/把元素item入栈;堆栈满时出错退出voidSeqStack:Push(constDatatype/然后top加1,/出栈并返回栈顶元素;堆栈空时出错退出DatatypeSeqStack:Pop()if(top=0)cout堆栈已空!endl;exit(1);top-;/top先减1 returndatatop;/然后取top位置上的元素返回,/取栈顶元素返回DatatypeSeqStack:Peek(void)const if(top=0)cerr堆栈空!endl;exit(1);returndatatop-
22、1;/top指在栈顶的下一个位置,取top-1上的元素返回,2.继承类定义和实现方法 继承类定义指考虑顺序堆栈类数据成员对顺序表类数据成员继承性的定义。includeSeqList.hclassSeqStack:privateSeqList public:SeqStack(void);/构造函数 SeqStack(void);/析构函数 voidPush(constDatatype/元素item入栈,DatatypePop(void);/出栈元素并返回 DatatypePeek(void)const;/读栈顶元素并返回 intStackEmpty(void)const;/栈空时返回1;否则返回
23、0 intGetSize(void)const;/读栈元素个数size voidClearStack(void);/清空堆栈使之为初始化状态;,在以下SeqStack类的实现中都是调用了基类SeqList的公有成员函数,因为是private派生方式,所以此时基类SeqList的所有公有成员函数成为派生类SeqStack的私有成员函数。派生类SeqStack通过调用基类SeqList的公有成员函数来实现成员函数的功能。,/构造函数SeqStack:SeqStack(void)SeqList();/把元素item入栈;栈满时出错退出voidSeqStack:Push(constDatatype,I
24、nsert(item,ListSize();/在当前顶部位置插入元素/出栈并返回栈顶元素;栈空时出错退出DatatypeSeqStack:Pop(void)if(ListSize()=0)cerr堆栈已空!endl;exit(1);returnDelete(ListSize()-1);/删除最后存入的元素并返回,/取栈顶元素返回DatatypeSeqStack:Peek(void)const returnGetData(ListSize()-1);/取最后存入的元素返回/判堆栈空否,空返回1;非空返回0intSeqStack:StackEmpty(void)const returnListEm
25、pty();/读栈元素个数sizeintSeqStack:GetSize(void)const returnListSize();,/清空堆栈使之为初始化状态voidSeqStack:ClearStack(void)ClearList();上述文件名为CSeqStack.h。,3.3.2 顺序堆栈应用表达式计算 堆栈是各种软件系统中应用最广泛的数据结构之一。例如,表达式计算是编译系统中的基本问题,其实现方法是堆栈的一个典型应用。在编译系统中,要把便于人理解的表达式翻译成能正确求值的机器指令序列,通常需要先把表达式变换成机器便于理解的形式,这就要变换表达式的表示序列。借助顺序堆栈即可实现这样的变
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第3章 顺序存储结构的表、堆栈和队列 顺序 存储 结构 堆栈 队列
链接地址:https://www.desk33.com/p-740035.html