第三章+线性表.ppt_第1页
第三章+线性表.ppt_第2页
第三章+线性表.ppt_第3页
第三章+线性表.ppt_第4页
第三章+线性表.ppt_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

,第三章线性表ChapterThreelinearform,【教学提示】采用理论联系实践、配合实例的方式进行讲解,重点讲解线性表的逻辑结构、存储结构及相关应用,体会数据结构中逻辑结构与存储结构之间的对应关系。双向链表、循环链表等内容可作为选学内容。,【内容简介】线性表是数据结构中最基本的结构之一,其应用非常广泛,在高级语言程序设计中经常遇到的数组就是线性表的应用。按线性表的存储结构,可将其分为顺序表和链表,通过对其操作可以解决许多生活中的实际问题。,【知识要点】线性表的概述和基本概念;顺序表的基本操作及综合应用;链表的基本操作及综合应用;实例应用。,【KnowledgePoints】outlinedoftheLinearformandbasicconcepts;Thebasicoperationoftheorderformandintegratedapplication;basicoperationsofListandintegratedapplication;Applicationexamples。,3.1实例引入【学习任务】通过实例初步了解线性表的特征,从感性上认识线性表及其简单操作。【例3.1】对于初学计算机者,会遇到计算机打字练习,目前有很多指法练习软件,其中打字游戏集娱乐和学习于一体,是计算机初学者比较喜欢使用的打字练习软件。图3.1所示为打字游戏界面。,图3.1打字游戏界面,图3.2英文打字练习示意图,对于如图3.1所示的英文打字软件,是对单个字符进行练习的,如图3.2所示的界面是对多个英文字符进行练习,练习时,若输入正确的字母,以蓝色显示;若输入错误的字母,会给出相应提示或显示其他颜色(假设为红色)。在如图3.2所示的提示信息中,给出的字母就是按照顺序排列的,其中包含了字母、空格等符号,用户可以按照字母出现的先后顺序进行操作,根据这样的提示输入的信息就是典型的基于前后关系的线性结构。,【例3.2】假设现在有一篇英文文章,某用户想在其中查找某单词,则首先要将这些单词以前后出现的顺序存放在一张表中,假设为A=(a1,a2,ai1,ai,ai+1,an),要在其中查找某单词时,可按顺序从a1开始,一直找到最后,如果有匹配的单词存在,则查找成功,否则查找失败。如果查找的过程是在类似于以字母为顺序的字典中进行的,则可以先确定该单词的第一个字母所在位置,然后进一步查找单词具体位置,这些具体操作是基于表A的建立方式不同而不同的。这里表A也是一个线性表的实例。,3.2线性表的概述【学习任务】理解线性表的含义,熟练掌握线性表的相关概念,重点理解线性表中逻辑结构、存储结构和相应操作之间的关系。3.2.1线性表的概念通过前面的例子可以看出,线性表实际上是基于前面元素和后面元素之间的一种相邻关系的结构。1线性表的定义线性表是将多个具有相同类型的数据元素放在一起构成一组有限序列的结构,通常记为A=(a1,a2,ai1,ai,ai+1,an),3.2.1TheconceptofthelinearformLinearformismorewiththesametypeofdataelementstogetherandformthestructureofafinitesequence,usuallydenotedA=(a1,a2,.,ai-1,ai,ai+1,.,an),2线性表的相关概念在上述线性表的定义中,相关概念如下。(1)A代表一个线性表。(2)ai(1in)称为线性表的元素,i为元素的下标,表示该元素在线性表中的位置。(3)线性表中n为表长,其中,n0,当n=0时称该表为空表。,(4)线性表是一种基于相邻数据元素之间的对应关系,将元素ai1称为元素ai的直接前趋,将元素ai+1称为元素ai的直接后继。通过定义可知,在线性表中,a1是表中第一个元素,它没有前趋,an是最后一个元素,没有后继。(5)线性表中的元素ai既可以是一个单个元素,也可以是一个数据元素,即由多个数据项构成的元素。例如,在第1章中所介绍的图书信息表中,一个记录即为一个元素,它包括多个数据项(图书编号、书名、数量、价格)。,因此,线性表的定义也可描述如下:线性表是第一个元素无前驱,最后一个元素无后继,而其他元素都有唯一直接前驱和直接后继的表结构。例如,A=(1,4,7,49)是一个线性表,每个数值就是一个元素。B=(2001,计算机应用基础,10,22),(2003,大学英语,30,14),(2005,机械制图,70,30),(2007,数据结构,35,24)也是一个线性表,每个元素是由4个数据项(图书编号、书名、数量、价格)构成的。,3.2.2线性表的存储结构及操作1线性表的逻辑结构(Logicalstructure)与存储结构(Storagestructure)由线性表的定义可知线性表的逻辑结构,即相临元素之间所满足的前驱和后继的逻辑关系。如果要在计算机中实现对线性表的各种操作,必须了解线性表在计算机中的存储形式(即存储结构)。一种逻辑结构可对应多种存储结构,而每种存储结构又有自己的存储特点和操作方式。,2线性表的操作线性表的常见操作有:建表(初始化)、求表长、查找、插入、删除等。线性表的操作是在其逻辑结构和存储结构的共同支持下完成的。值得注意的是,每种数据结构的相关操作一定不能脱离其逻辑结构和存储结构而独立存在。3线性表的分类线性表的存储结构可分为顺序存储结构和链式存储结构两种,因此可将线性表分为顺序表和链表两大类。下面分别介绍顺序表和链表的特点及操作。,2operationofLinearformcommonoperationsofLinearformare:buildingtable(initialization),seekingalongtable,find,insert,deleteandsoon.Lineartableoperationisonthejointsupportofitslogicalstructureandstoragestructure.,3.3顺序表的基本操作及实现【学习任务】理解线性表在顺序存储结构下的特点,掌握顺序表的表示、相关算法及程序实现。,3.3.1顺序表的概述1定义顺序表是指线性表在顺序存储形式下构成的表2存储特点顺序表的存储是指在内存中,在一段连续的存储单元中存储线性表。其特点为,线性表逻辑上相邻的数据元素(直接前驱和直接后继)在存储位置(或物理位置)上也相邻,如图3.3所示。,3.3.1OverviewoftheSequencetable1.DefinitionSequencetableisstoredinlinearformintheorderformconstitutethetable.2.StorageFeaturesSequencetableisstoredinmemory,inastorageunittostoreacontinuouslinearform.,图3.3线性表的逻辑结构和存储结构对应图,在上述表示中,m为该顺序表存储的首地址,d为每个元素占用的存储空间,因此在顺序表的存储结构中,有如下的对应关系。设a的存储地址为m,每个数据元素占d个存储单元,则第i个数据元素的地址为Loc(ai)=m+(i1)*d1in,即只要知道顺序表的首地址和每个数据元素所占的字节数,就可求出第i个数据元素的地址,这也是顺序表具有按数据元素的序号随机存取的特性。通过前面的介绍,可知顺序表非常适合用高级语言中的数组去实现。值得注意的是,探讨某种数据的操作一定是在一定的逻辑结构和存储结构之上进行的操作。,3.3.2顺序表的基本操作及实现顺序表的基本操作包括建立、插入、删除、查找等,下面就重点说明插入、删除等操作的实现算法。1顺序表的表示为实现顺序表的各种操作,首先必须了解顺序表的表示方法,顺序表由两个量表示,即表示同种数据类型的数组和表示数组长度的整型变量。,【例3.3】以整型数组的表示为例,类如下:publicclassLineListprivateintdata;privateintlength;publicLineList()publicvoidsetData(intdata)this.data=data;publicvoidsetLength(intlength)this.length=length;publicintgetData()return(this.data);publicintgetLength()return(this.length);说明:该类定义的是整型数组,在实际应用中,可根据具体情况而定;类中的成员设置为private的,对外不可见。这就是类的封装性。,2插入操作及程序实现顺序表的插入是指在现有表结构的基础上,在规定位置插入和顺序表相同性质的元素,插入操作具体过程及结果为:首先确定插入位置i,按照anai的顺序由后至前依次将各元素向后移动,为新元素让出位置,将新元素x插入已经让出的第i个位置,结束插入操作,结果如图3.4所示。,图3.4顺序表的插入操作示意图,(2)线性表的顺序表插入操作ListInsert(if(length=data.length)/表空间已经满,不能插入System.out.println(Thetableisoverflow.);returnfalse;if(ilength)/插入位置是否正确System.out.println(Thepositionismistake.+i);returnfalse;for(j=length-1;j=i;j-)dataj+1=dataj;datai=a;length+;returntrue;,说明:顺序表算法的实现是通过移动元素实现的,如果插入位置比较靠前,则需要移动大量元素;顺序表插入操作要注意数组的长度和插入位置的判断,否则会出现错误。3删除操作及程序实现顺序表的删除是指在现有表的基础上,在规定位置删除某元素,删除操作的具体过程及结果为如下:首先确定删除位置i,按照ai+1an的顺序依次将各元素向前移动,将元素ai删除,结束删除操作,结果如图3.5所示。,图3.5顺序表的删除操作示意图,(3)线性表的顺序表删除操作ListDelete(if(i=length)/检查删除位置是否存在System.out.println(Thepositionismistake.);returnfalse;for(j=i;jlistsize=Lc.length=La.length+Lb.length;Pc=Lc-elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType);If(!Lc.elem)exit(overfiow);Pa_last=La.elem+La.length-1;pb_last=Lb.elem+Lb.length-1;While(pa=pa_last,时间复杂度?,3.4链表的基本操作及实现【学习任务】理解线性表在链式存储结构下的特点,掌握链表的表示、相关算法及程序实现。1链表的定义链表也是一种有顺序的表,其内容可以存储在一组任意的存储单元中,所谓任意的存储单元,即这组存储单元可以是连续的,也可以是不连续的,这就需要在存储元素本身信息的同时,还要存储下一个元素的位置,由此构成一个链状结构,称其为链表,如图3.6所示。,3.4thebasicoperationsandachievementoflist1.Definitionoflistlistisalsoasequentialtable,theircontentcanbestoredinastorageunitinanyso-calledarbitrarymemorycell,thatthisgroupofstorageunitscanbecontinuous,itmaybediscontinuous,andthisrequiresthestorageelementsoftheirinformationisalsonecessarytostorethelocationofthenextelement,thusformingachainstructure,calledthelist.,图3.6带头指针头结点的链表示意图,2链表的相关概念将表示数据元素和下一个元素位置的结构称为链表的结点。若第一个结点只表示整个链表的起始位置,而无任何信息,称其为头结点。对于最后一个结点,后面无任何元素,其表示元素位置的地址用“”来表示,称其为尾结点,程序实现中用“null”来表示,如图3.6所示。,2.relatedconceptsofListnodes:Torepresentdataelementsandthelocationofthenextelementinthestructurecalledthelinkedlistofnodesfirstnode:Ifthefirstnodethatthewholelistonlythestartingposition,withoutanyinformation,callthefirstnode.endnode:Forthelastnode,thebackwithoutanyelement,itslocationaddressesthatelementtorepresent,callingittheendnode,theprogramachievedusingnull.,3链表的表示链表中结点的表示必须要用到两个区域,其中一个存放数据元素自身的信息ai,称为数据域(DataDomain);另一个存放下一个元素的地址或位置,以保证表的连续性,称为指针域(PointerDomain)。链表中结点的表示如下:,在C/C+等语言中,提供指针以表示某元素的地址,但是这样可能会造成比较大的风险。因此,Java语言提出了利用java.util.LinkedList的类库提供的链表类供编程者使用.用户可以通过该类库简单地实现指针操作本章通过另外的方式来实现链表的存储,即利用数组的方式实现链表的存储以及算法的实现,为此定义如下结构的类:,publicclassLinkNodeprivateintdata=-1;privateLinkNodenext=null;publicvoidsetData(intdata)this.data=data;publicvoidsetNext(LinkNodenext)this.next=next;publicintgetData()return(this.data);publicLinkNodegetNext()return(this.next);设该链表中存储的内容为字符串“study”,链表表示如图3.6所示。,图3.6带头指针头结点的链表示意图,【例3.4】假设有如下逻辑结构的线性表A=(a1,a2,a9),用数组表示的链表对应关系如图3.7所示。,图3.7数组表示的链表之间对应关系示意图,第1个数组存放的是链表表示的数据,第2个数组存放的是第一个数组中数据之间的前后关系。例如链表从数组下标为7的元素a1开始,由第2个数组对应的下标为7的元素数值,得出下一个元素a2所在的位置为3(即第4个元素),然后继续从第2个数组a2的数值为6(即第7个元素),以此类推,最终得出全部元素。这样可用两个数组配合来表示链表。当用链表表示线性表时,由于不是按照元素的顺序进行存储的,因此一定要知道第一个元素的位置(即链表的首位置,用Head表示),同时还要知道最后一个元素的结束标志(即链表的末位置,用表示)。,3.4.2链表的分类按照链表的组成方式,可将链表分为单链表、双向链表、循环链表等。下面以单链表为例进行介绍,其他链表以此类推即可。1单链表(Singlelinkedlist)单链表是链表中最常用的一种,也是结构比较简单的一种,是由第1个元素到最后一个元素构成的一个链,其特点从第1个元素(可能有头指针和头结点)到最后一个元素(结束标志为)构成的一个链,称为单链表,如图3.6所示。单链表的特点是通过前一个元素的指针域可以顺序找到后面元素所在的位置,因此所有操作全部是从第1个元素(头指针或头结点)开始的。,2循环链表(Circularlinkedlist)在单链表中,最后一个元素的存储区域是,如果将它指向第1个元素(头结点)位置,就构成了循环链表。如链表中存储的内容为字符串study,其循环链表表示如图3.8所示。,图3.8带头指针头结点的循环链表示意图,循环链表的特点是在所有元素之间构成一个环,从任何一个元素出发,都可以查找其他所有的元素,同时还充分地利用了空间。,3双向链表(Two-waylinkedlist)前面两种链表的查找方式都是沿着一个方向进行的,对于元素比较少的链表进行操作时比较方便;但当元素数量非常多时,若只沿着一个方向进行操作,有时操作不是很方便,因此,若每个元素都可以向两个方向进行查找元素,就大大提高了操作效率,这就构成了双向链表。假设,该链表中存储的内容为字符串study,其双向循环链表表示如图3.9所示。,该链表的特点是可以从任何一个元素出发,向两个方向分别查找相应元素,可提高操作效率。,实际上,链表还可以构成更多的种类,如双向循环链表等,通过前面对链表分类的介绍,应该清楚,无论使用哪种形式的链表,其操作都是相通的。,图3.9带头指针头结点的双向链表示意图,3.4.3单链表的基本运算及实现和顺序表的操作类似,单链表的操作也有很多,如单链表的建立、插入、删除,元素的查找、替换等。下面以单链表的插入、删除操作为例进行讲解。1在单链表的指定位置进行插入操作【例3.5】建立一个单链表,将字符串STUDY存储在该链表中。根据题意,其操作可分为如下步骤。,(1)创建单链表并进行初始化操作建立一个头结点(Head),为其申请空间,如图3.10所示。,图3.10建立头结点Head,(2)在单链表的表头位置插入元素以如图3.10所示的单链表为基础,依次将元素插入到表头位置,实现将“STUDY”倒置存放到该单链表中,如图3.11所示,表示已经将“TUDY”存放到单链表中。,图3.11插入元素TUDY后的单链表,最后,将S插入到如图3.11所示的单链表中,先为元素S申请一个结点,用new表示,将其插入到如图3.11所示的单链表中,实现语句为inp=newOnelinkNode(2);inp.next=Head;Head=inp;最后,得到如图3.12所示的单链表,图3.12插入结点S后的单链表,(3)在单链表的中间位置插入元素设在如图3.11所示的单链表中,插入一个元素R,使其变成STUDRY,其操作如下:首先,确定插入位置,用指针minp来表示;然后执行如下语句,完成插入操作。inp=newOnelinkNode(3);inp.next=minp.next;minp.next=inp;其结果如图3.13所示。,图3.13中间插入元素后的单链表,2在单链表中进行删除操作【例3.6】对于用单链表表示的STUDY,若将U删除,应如何操作。首先,确定删除元素的位置用delq表示,将该元素前一个位置用delp表示;然后执行如下语句。delp.next=delq.next;或者delp.next=(delp.next).next;结果如图3.14所示。,图3.14在单链表中删除元素U,3.4.4其他形式的链表的相关运算对于双向链表和循环链表,其操作和单链表非常类似,首先确定操作位置,在操作时,要注意在指针变化过程中,要满足先连线,再改变指针位置的操作顺序,否则就会出现结点丢失问题。,3.4.5算法实例【算法3.3】在链表的头部插入结点。publicclassLinkNodeprivateintdata=-1;privateLinkNodenext=null;publicvoidsetData(intdata)this.data=data;publicvoidsetNext(LinkNodenext)this.next=next;publicintgetData()return(this.data);publicLinkNodegetNext()return(this.next);,publicclassLinkTableprivateLinkNodehead=null;privateintcounts=0;publicvoidinsert(intd)if(head=null)head=newLinkNode();LinkNoden=newLinkNode();/定义新的链表结点,并将数据赋给新结点n.setData(d);if(head.getNext()=null)/如果头结点的后继无结点,注意头结点中无数据head.setNext(n);elsen.setNext(head.getNext();/如果头结点的后继结点存在head.setNext(n);counts+;/结点总数增加publicvoidprint()LinkNoden=head.getNext();intiCounter=1;while(n!=null)System.out.print(n.getData()+);n=n.getNext();iCounter+;,publicintsize()returnthis.counts;publicstaticvoidmain(Stringargs)LinkTablelinkTable=newLinkTable();linkTable.insert(30);linkTable.insert(23);linkTable.insert(12);linkTable.insert(50);linkTable.insert(36);linkTable.insert(77);linkTable.insert(37);linkTable.print();程序运行的结果为37773650122330,3.5线性表的应用【学习任务】在学习线性表基础知识的前提下,掌握线性表在顺序存储结构和链式存储结构下的应用实例及程序实现。3.5.1顺序表的连接有两个顺序表A和B,其元素均按从小到大的升序排列,编写一个算法将它们合并成一个顺序表C,要求C的元素也是按从小到大的升序排列。算法思路:依次扫描通过A和B的元素,比较当前的元素的值,将较小值的元素赋给C,直到一个线性表扫描完毕,然后将未完的那个顺序表中余下的部分赋给C。C的容量要能够大于A、B两个线性表相加的长度即可。具体程序如下:,publicclassCombinatevoidmerge(inta,intb)inti,j,k;i=0;j=0;k=0;intalength=a.length;intblength=b.length;intclength=alength+blength;intc=newintclength;while(ialength,System.out.print(排序好的是:);for(intl=0;lclength;l+)System.out.print(+cl);publicstaticvoidmain(Stringargs)Combinatea1=newCombinate();inta=2,5,7;intb=3,4,8,9;System.out.print(a数组:);for(inti=0;ia.length;i+)System.out.print(+ai);System.out.println();System.out.print(b数组:);for(intj=0;jb.length;j+)System.out.print(+bj);a1.merge(a,b);,程序运行的结果为a数组:257b数组:3489排序好的是:2345789,3.5.2字符串的逆转算法假设有如下字符串“STUDY”,利用单链表存储该字符串,并实现将其逆转,即原字符串变为“YDUTS”,如图3.15所示。分析:根据单链表的插入和删除操作,其实现过程可以以H1为基础,将其第1个元素S作为单链表的末尾元素插入进来(这个过程实际已经完成);将第2个元素T从原来的H1中删除,然后插入到以H1为头,S为尾的单链表中去;然后按照这个过程依次将U、D、Y从原来的链表中删除,依次插入到原链表的首部,这样就实现了逆转。,图3.15单链表的逆转示意图,具体程序如下:classLinkCharNodeprivatechardata=0;privateLinkCharNodenext=null;publicvoidsetData(chardata)this.data=data;publicvoidsetNext(LinkCharNodenext)this.next=next;,publicchargetData()return(this.data);publicLinkCharNodegetNext()return(this.next);publicclassLinkCharTableprivateLinkCharNod

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论