下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
数据结构关联图
串n个字符的有限序列前驱后继数数据元素限制线性表的变型带头结点、循环、双向结点变化栈
插入、删除限定在一端进行的线性表队列插入限定在一端,删除在另一端进行的线性表操作限制数据元素扩展数组数据元素之间的关系在维数上扩充的线性表维数扩展广义表数据元素可以是表的线性表树每个结点可以有多个后继,但至多一个前驱图每个结点可以有多个后继和多个前驱线性表
n个数据元素的有限序列第二章线性表线性结构特点:在数据元素的非空有限集中存在唯一的一个被称作“第一个”的数据元素存在唯一的一个被称作“最后一个”的数据元素除第一个外,集合中的每个数据元素均只有一个前驱除最后一个外,集合中的每个数据元素均只有一个后继2.1线性表的类型定义定义:一个线性表是n个相同类型数据元素的有限序列例英文字母表(A,B,C,…..Z)是一个线性表例数据元素特征:元素个数n—表长度,n=0空表1<i<n时ai的直接前驱是ai-1,a1无直接前驱ai的直接后继是ai+1,an无直接后继i为数据元素ai在线性表中的位序ADTList{线性表的抽象数据类型定义数据对象:D={ai|ai∈ElemSet,i=1,2,...,n,n≥0}1}ADTList数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,...,n}2基本操作:结构初始化操作结构销毁操作引用型操作加工型操作32.1.1线性表的定义Data_Structure=(D,L,S,O)基本操作O:是在逻辑结构上对数据结构或数据元素的一组基本运算,与具体实现无关;可利用给定的基本操作构造更复杂的运算如:线性表初始化;求线性表的长度;按值查找;插入元素操作;删除元素操作等
StatusList_Init(ListPtrL)初始条件:表L不存在。操作结果:成功返回success,构造一个空的线性表L;否则返回fatal。(1).线性表初始化操作:假设:所有操作都通过函数来实现,函数通常包括函数名字、返回类型、函数参数以及函数体(具体实现),其中函数参数包括参数个数、参数类型和参数顺序。线性表定义为指针类型ListPtr,数据元素类型为ElemType
voidList_Destory(ListPtrL)初始条件:表L存在。操作结果:释放L所占空间。⑵销毁线性表操作:
voidList_Clear(ListPtrL)初始条件:表L存在。操作结果:清除线性表L的所有元素,L变为空表。⑶线性表清空操作:
boolList_Empty(ListPtrL)初始条件:表L存在。操作结果:线性表L空返回true,否则返回false。
⑷线性表判空操作:
intList_Size(ListPtrL)初始条件:表L存在。操作结果:返回线性表L中的所含数据元素的个数。⑸求线性表的长度操作:
StatusList_Retrieve(ListPtrL,intpos,ElemType*elem)初始条件:表L存在。操作结果:若1<=pos<=List_Size(L),返回success,同时将线性表L中的第pos个元素的值存放在elem中;否则返回range_error。⑹取表中元素操作:
StatusList_Locate(ListPtrL,ElemTypeelem,int*pos)初始条件:表L存在,elem是给定的一个数据元素。操作结果:在表L中查找首次值为elem的数据元素,若找到,返回success,同时将L中首次值为elem的数据元素的序号记入pos;否则,返回fail。⑺按值查找操作:
StatusList_Insert(ListPtrL,intpos,ElemTypeelem)初始条件:表L存在。操作结果:若1<=pos<=List_Size(L)+1,且线性表中还有未用的存储空间,在线性表L的第pos个位置上插入一个值为elem的新元素,原序号为pos,pos+1,...,n的数据元素的序号变为pos+1,pos+2,...,n+1,插入后表长=原表长+1,返回success;否则,若没有空间返回overflow,位置不对返回range_error。⑻插入操作:
StatusList_Remove(ListPtrL,intpos)初始条件:表L存在。操作结果:若1<=pos<=List_Size(L),在线性表L中删除序号为pos的数据元素,删除后使序号为pos+1,pos+2,...,n的元素的序号变为pos,pos+1,...,n-1,新表长=原表长-1,返回success;否则返回range_error。⑼
删除操作:StatusList_Prior(ListPtrL,int*pos,ElemTypeelem)初始条件:表L存在。操作结果:若第pos个数据元素的直接前驱存在,将其存入elem中,返回success;否则返回fail。⑽
求前驱操作:
StatusList_Next(ListPtrL,int*pos,ElemTypeelem)初始条件:表L存在。操作结果:若第pos个数据元素的直接后继存在,将其存入elem中,返回success;否则返回fail。⑾
求后继操作:例1:合并线性表问题:集合A和B分别用两个线性表LA和LB表示,求A∪B并用线性表LA表示。算法设计:思想:从LB中逐一取出元素,判该元素是否在LA中,若不在则将该元素插入到LA中。细化:到实现程度逐一:从第一个到最后一个,计数型循环,前提是需要知道元素个数如何取出第i个数据元素bi?如何判断bi是否已在A中?如果不在A中,怎样实现将bi插入?1.依次从LB中取出第i个数据元素;2.判elem是否在LA中存在;3.若不存在,则将elem插入到LA中。List_Retrieve(Lb,i,&elem)→elem
List_Locate(La,elem,&j)
List_Insert(La,1,elem)用基本操作实现:StatusList_Union(ListPtrLa,ListPtrLb){
ElemTypeelem;/*存放从Lb中取出的元素*/Statusstatus;/*状态代码*/
inti,j,len=List_Size(Lb);/*len存放Lb的元素个数*/
for(i=1;i<=len;i++){
List_Retrieve(Lb,i,&elem);/*取出Lb中第i个数据元素*/status=List_Locate(La,elem,&j);/*判它是否在La中*/if(status!=success){/*如果不在*/status=List_Insert(La,1,elem);/*插入到第一个位置*/if(status!=success)break;/*插入失败则退出*/
}}
returnstatus;}例:合并线性表算法例:合并线性表算法分析如何分析?设m和n分别表示La和Lb的长度(元素个数)先确定基本操作----判断是否在La中基本操作执行次数是否确定?确定:次数不确定:最好/最坏/平均情况分析本例不确定最好情形分析B为A的前面部分元素:1+2+…+n=(n+1)*n/2最坏情形分析B∩A为空:m+(m+1)…+(m+n-1)=n*m+(n-1)*n/2优化?选数据元素个数少的作为Lb例2:合并有序表问题:已知线性表La和Lb中元素分别按非递减顺序排列,现要求将它们合并成一个新的线性表Lc,并使得Lc中元素也按照非递减顺序排列。分析:线性表Lc初始为空。依次扫描La和Lb中的元素,比较当前元素的值,将较小值的元素插入Lc的表尾之后,如此反复,直到一个线性表扫描完毕,然后将未完的那个线性表中余下的元素逐个插入到Lc的表尾之后细化:现有操作可实现否?StatusList_Merge(ListPtrLa,ListPtrLb,ListPtrLc){ElemTypeelem1,elem2;status=List_Init(Lc);inti=1,j=1,k=1;/*i,j,k分别用于指示La,Lb,Lc中当前元素*/intn=List_Size(La),m=List_Size(Lb);
while(i<=n&&j<=m){/*两个表都还未处理完*/List_Retrieve(La,i,&elem1);List_Retrieve(Lb,j,&elem2);if(elem1<elem2){status=List_Insert(Lc,k,elem1);i=i+1;}else{status=List_Insert(Lc,k,elem2);j=j+1;}k=k+1;}
while(i<=n){/*表La都还未处理完*/
List_Retrieve(La,i,&elem1);status=List_Insert(Lc,k,elem1);i=i+1;k=k+1;}
while(j<=m){/*表Lb都还未处理完*/List_Retrieve(Lb,j,&elem2);status=List_Insert(Lc,k,elem2);j=j+1;k=k+1;}returnstatus;}算法分析:该算法中包含了三个while语句,第一个处理了某一张表的全部元素和另一张表的部分元素;后两个while循环只可能有一个执行,用来完成将未归并到Lc中的余下部分元素插入到Lc中。“插入”是估量归并算法时间复杂度的基本操作,次数为两个表的元素个数之和:n+m该算法的时间复杂度为:O(n+m)若La和Lb的元素个数为同数量级n,则该算法的时间复杂度为:O(n)。2.1.2线性表的顺序存储结构顺序表:定义:用一组地址连续的存储单元存放一个线性表叫~元素地址计算方法:LOC(ai)=LOC(a1)+(i-1)*LLOC(ai+1)=LOC(ai)+L其中:L—一个元素占用的存储单元个数LOC(ai)—线性表第i个元素的地址LOC(a1)—起始地址,基地址特点:实现逻辑上相邻—物理地址相邻实现随机存取实现:可用C语言的一维数组实现#defineLIST_INIT_SIZE100#defineLISTINCREMENT10Typedefstruct{ElemType*elem;intlength;intlistsize;}SqList;元素序号a1a2anbb+lb+(n-1)l12n内存存储地址b+(maxlen-1)l备用空间数据元素不是简单类型时,可定义结构体数组动态申请内存L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));插入定义:线性表的插入是指在第i(1in+1)个元素之前插入一个新的数据元素x,使长度为n的线性表
变成长度为n+1的线性表
需将第i至第n共(n-i+1)个元素后移算法Ch2_1.c内存a1a2aiai+1an01i-1V数组下标n-1in12i元素序号i+1nn+1内存a1a2aiai+1an01i-1V数组下标n-1in12i元素序号i+1nn+1an-1x算法时间复杂度T(n)设Pi是在第i个元素之前插入一个元素的概率,则在长度为n的线性表中插入一个元素时,所需移动的元素次数的平均次数为:删除定义:线性表的删除是指将第i(1in)个元素删除,使长度为n的线性表
变成长度为n-1的线性表
需将第i+1至第n共(n-i)个元素前移算法Ch2_2.c内存a1a2aiai+1an01i-1V数组下标n-1in12i元素序号i+1nn+1内存a1a2ai+1V数组下标01i-1n-2in-112i元素序号i+1n-1nanai+2算法评价设Qi是删除第i个元素的概率,则在长度为n的线性表中删除一个元素所需移动的元素次数的平均次数为:故在顺序表中插入或删除一个元素时,平均移动表的一半元素,当n很大时,效率很低顺序存储结构的优缺点优点逻辑相邻,物理相邻可随机存取任一元素存储空间使用紧凑缺点插入、删除操作需要移动大量的元素预先分配空间需按最大空间分配,利用不充分表容量难以扩充2.1.3线性表的链式存储结构特点:用一组任意的存储单元存储线性表的数据元素利用指针实现了用不相邻的存储单元存放逻辑上相邻的元素每个数据元素ai,除存储本身信息外,还需存储其直接后继的信息结点
数据域:元素本身信息指针域:指示直接后继的存储位置数据域指针域结点ZHAOQIANSUNLIZHOUWUZHENGWANG^H例线性表(ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG)43131NULL3771925数据域指针域LIQIANSUNWANGWUZHAOZHENGZHOU存储地址1713192531374331H头指针实现typedefstructLNode{
ElemType
data;structLNode*next;}LNode,*LinkList;LNode*h,*p;datanextp结点(*p)(*p)表示p所指向的结点(*p).datap->data表示p指向结点的数据域(*p).nextp->next表示p指向结点的指针域生成一个新结点:p=(LinkList)malloc(sizeof(Lnode));系统回收p结点:free(p)线性链表定义:结点中只含一个指针域的链表叫~,也叫单链表头结点:在单链表第一个结点前附设一个结点叫~头结点指针域为空表示线性表为空ha1a2头结点an^…...h空表^单链表的基本运算查找:查找单链表中是否存在结点X,若有则返回指向X结点的指针;否则返回NULL算法描述While循环中语句频度为若找到结点X,为结点X在表中的序号否则,为npabxs算法评价插入:在线性表两个数据元素a和b间插入x,已知p指向as->next=p->next;p->next=s;算法描述算法评价Ch2_4.c算法描述pabc算法评价删除:单链表中删除b,设p指向ap->next=p->next->next;Ch2_5.c动态建立单链表算法:设线性表n个元素已存放在数组a中,建立一个单链表,h为头指针算法描述算法评价h头结点an^0h头结点an-10an^a2…...h头结点an-10an^ha1a2头结点an^…...0Ch2_6.ch头结点0^单链表特点它是一种动态结构,整个存储空间为多个链表共用不需预先分配空间指针占用额外存储空间不能随机存取,查找速度慢循环链表(circularlinkedlist)循环链表是表中最后一个结点的指针指向头结点,使链表构成环状特点:从表中任一结点出发均可找到表中其他结点,提高查找效率操作与单链表基本一致,循环条件不同单链表p或p->next=NULL循环链表p或p->next=hhh空表双向链表(doublelinkedlist)单链表具有单向性的缺点结点定义typedefstructDuLNode{ElemTypetata;structDuLNode*prior,*next;}DuLNode,*DuLinkList;priorelementnextL空双向循环链表:非空双向循环链表:LABbcapp->prior->next=p=p->next->proir;bcaP删除算法描述算法评价:T(n)=O(1)p->prior->next=p->next;p->next->prior=p->prior;Status
ListDelete_Dul(DuLinkList&L,inti,ElemType&e){if(!(p=GetElemP_Dul(L,i)))returnERROR;e=p->data;p->prior->next=p->next;
p->next->prior=p->prior;
free(p);returnOK}StatusListInsert_Dul(DuLinkList&L,inti,ElemTypee){if(!(p=GetElemP_Dul(L,i)))returnERROR;if(!(s=(DuLinkList)malloc(sizeof(DuLNode)))) returnERRORs->data=e;
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
returnOK}算法描述算法评价:T(n)=O(1)xSbaP插入4.静态链表某些语言中不提供指针,如Java和VisualBASIC等,则只能通过其他方式来模拟指针采用数组模拟链表的指针,用以表示数据元素后继所存放位置数据元素的存储空间像顺序表一样是事先静态分配的数据元素之间的关系像链表一样是显示的
dataNexthead=004
1a45
29
3a31
4a18
5a5-1av=667
72
8a23
910
1011
11-1顺序与链式存储结构比较顺存储结构的特点逻辑上相邻的元素,其物理位置也相邻;可随机存取表中任一元素必须按最大可能长度预分存储空间,存储空间利用率低,表的容量难以扩充,是一种静态存储结构插入删除时,需移动大量元素,平均移动元素为n/2链式存储结构的特点逻辑上相邻的元素,其物理位置不一定相邻;元素之间的邻接关系由指针域指示是非随机存取存储结构;对链表的存取必须从头指针开始是一种动态存储结构;插入删除运算非常方便;只需修改相应指针值2.1.5
线性表的应用存储结构选择原则各有优缺点,选择那一种存储结构由实际问题中的主要因素决定(1)基于存储空间的考虑:线性表的长度或存储规模难以估计时,或数据元素动态变化较大时,使用链表(2)基于运算时间的考虑:经常做的是访问数据元素操作,插入删除操作极少时用顺序表(3)基于实现的考虑:顺序表的实现较为简单,链表的实现较为复杂1.线性表倒置问题:把线性表(a1,a2,…,an)变为(an,an-1,…,a1)算法:算法1:对应数据元素相交换,如a1与an交换、a2与an-1交换等等算法2:前驱后继关系改变,即倒置前a1是a2的前驱、a2是a1后继,倒置后a1是a2的后继、a2是a1前驱,……实现:顺序表上实现单链表上实现1.线性表倒置在顺序表上按算法1(对应数据元素相交换)实现P.41:voidList_Reverse(ListPtrL){inti=1,j=L->length; ElemTypetemp; while(i<j){ temp=L->elem[i]; L->elem[i]=L->elem[j]; L->elem[j]=temp; i++;j--;
}}思考:能否用for循环?1.线性表倒置在单链表上按算法2(前驱后继关系互换)实现P.42:voidList_Reverse(ListPtrL){ListNodePtrq,p=(*L)->next;/*p指向第一个数据结点*/(*L)->next=NULL;/*将原链表置为空表*/while(p){q=p;p=p->next;q->next=(*L)->next;/*插到头结点的后面*/(*L)->next=q;
}}线性表元素按照访问频度排序问题:设计一个在线性表中实现Locate运算的函数,使得线性表中所有结点按访问频度递减的顺序排列,以使访问频繁高的结点总是靠近表头分析:运算主要包括查找如果该元素比前一个频繁,则需要将其向前移动,也就是插入和删除操作结构选择查找:顺序或者链式均可;插入删除:链式存储综合:选择链式哪种链式结构呢?涉及前驱操作:双向链表线性表元素按照访问频度排序选用带头结点的双向链表L,每个结点有4部分: 指向前驱结点的指针prior
指向后继结点的指针next
存放数据的成员data
记载访问频度freq,初始时所有结点的freq都为0。首先在链表中查找指定数据,如找到,将其freq加1,然后向前寻找freq大于它的结点,并在该结点后面进行插入。priorfreqdatanext线性表元素按照访问频度排序voidLocate(DuListL,ElemTypex){
pNodep=L->next,q; while(p&&p->data!=x)p=p->next;/*定位*/ if(p){
/*链表中存在x*/ p->freq++; /*该结点的访问频度加1*/ q=p; /*从链表中摘下这个结点*/ if(p->prior)p->prior->next=p->next; if(p->next)p->next->prior=p->proir; p=q->prior;
while(p!=L&&q->freq>p->freq)/*寻找插入位置*/ p=p->prior; q->next=p->next; /*插入在p之后*/ q->prior=p; if(p->next)p->next->prior=q; p->next=q;
} else Error("Notfound!\n"); /*没找到*/}typedefstructnode{ElemTypedata;intfreq;structnode*prior,*next;}*DuList,*pNode;priorfreqdatanext思考:能否不要第二个循环?2.4线性表的应用举例一元多项式的表示及相加一元多项式的表示:可用线性表P表示但对S(x)这样的多项式浪费空间一般其中用数据域含两个数据项的线性表表示其存储结构可以用顺序存储结构,也可以用单链表单链表的结点定义typedefstructnode{intcoef,exp;structnode*next;}JD;coefexpnext-1A703198517^-1B81227-98^-1C70111227517^一元多项式相加设p,q分别指向A,B中某一结点,p,q初值是第一结点,结果保存在A中比较p->exp与q->expp->exp<q->exp:p结点是和多项
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 文言文双文本阅读:颜蠋与齐王游(附答案解析与译文)
- 小学一年级10到20加减法练习题,口算
- 小学数学五年级小数加减乘除法口算练习题
- 学度第一学期末高三级地理科期末考试试卷
- 高考语文试题分类汇编标点符号
- 广东省深圳市罗湖区高三2023-2024学年上学期1月期末英语试题
- 服饰设计师工作总结设计时尚服装引领潮流
- 文化艺术话务员工作总结
- 医疗器械销售人员工作总结
- 证券投资行业市场总结
- 高二期末考试动员主题班会
- 易错题(试题)-2024一年级上册数学北师大版含答案
- 滕州市九年级上学期期末语文试题(原卷版+解析版)
- EPC项目投标人承包人工程经济的合理性分析、评价
- 三相三线计量装置运行状态评估与错接线排障、反窃电现场处置技巧
- 房建工程监理大纲范本(内容全面)
- JB-T9092-1999阀门的检验与试验
- 社区电动车棚新(扩)建及修建充电车棚施工方案(纯方案-)
- 钣金行业的年度计划
- 代谢性脑病教学查房
- 全国职业学校教师说课大赛一等奖电工技能与实训《触电急救方法说课》说课课件
评论
0/150
提交评论