版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、顺序表的 特点:运算:简单,时间复杂度好存储特性:静态规模,编译前确定问题:程序的通用性和空间利用率之间的矛盾期望:在实际运行过程中,根据实际问题的需要临时确定存储空间,涉及到动态变量动态变量:在程序运行的过程中产生和释放的变量。与之相反的是静态变量静态变量:在程序运行的过程中一直存在的变量。静态变量是出现在说明语句中的变量;动态变量由于是在运行中产生的,因而不会事先说明如何实现动态变量?通过指针来实现:指针变量的说明,动态变量的产生和释放。2.3 线性链表及其运算线性链表及其运算线性表的链式存储结构称为线性链表,即将表中元素用线性表的链式存储结构称为线性链表,即将表中元素用链地址连接起来。链
2、地址连接起来。head头指针结点对线性表中的每一个数据元素,都需用两部分来存储:一部分用对线性表中的每一个数据元素,都需用两部分来存储:一部分用于存放数据元素值,称为数据域;另一部分用于存放直接前驱或于存放数据元素值,称为数据域;另一部分用于存放直接前驱或直接后继结点的地址(指针),称为指针域,称这种存储单元为直接后继结点的地址(指针),称为指针域,称这种存储单元为结点。结点。 链表的存储结构 链式存储结构是利用任意的存储单元来存放线性表中的元素,链式存储结构是利用任意的存储单元来存放线性表中的元素,存储数据的单元在内存中可以连续,也可以零散分布。存储数据的单元在内存中可以连续,也可以零散分布
3、。 由于线性表中各元素间存在着线性关系,每一个元素有一个直接由于线性表中各元素间存在着线性关系,每一个元素有一个直接前驱和一个直接后继。为了表示元素间的这种线性关系,在这种结前驱和一个直接后继。为了表示元素间的这种线性关系,在这种结构中不仅要存储线性表中的元素,还要存储表示元素之间逻辑关系构中不仅要存储线性表中的元素,还要存储表示元素之间逻辑关系的信息。所以用链式存储结构表示线性表中的一个元素时至少需要的信息。所以用链式存储结构表示线性表中的一个元素时至少需要两部分信息,除了存储每一个数据元素值以外,还需存储其后继或两部分信息,除了存储每一个数据元素值以外,还需存储其后继或前驱元素所在内存的地
4、址。两部分信息一起构成链表中的一个结点。前驱元素所在内存的地址。两部分信息一起构成链表中的一个结点。结点的结构如下所示。结点的结构如下所示。datanext数 据 域指 针 域链表结构示意图链表结构示意图4h e a d头 指 针1234567891 0d a t an e x tA7B2C9D1E0( a ) 线 性 链 表 的 物 理 状 态头指针headABCDE47291(b)线性表的逻辑状态 从图中可见,每个结点的存储地址存放在直接前驱的指针域中。从图中可见,每个结点的存储地址存放在直接前驱的指针域中。所以要访问链表中数据元素所以要访问链表中数据元素C,必须由头指针必须由头指针hea
5、d得到第一个结点得到第一个结点(数据(数据A)的地址,由该结点的指针域得到第二个结点(数据的地址,由该结点的指针域得到第二个结点(数据B)的的地址,再由其指针域得到存储数据地址,再由其指针域得到存储数据C的结点地址,访问该结点的数据的结点地址,访问该结点的数据域就可以处理数据域就可以处理数据C了。链表这种顺着指针链依次访问数据元素的特了。链表这种顺着指针链依次访问数据元素的特点,表明链表是一种点,表明链表是一种顺序存储结构顺序存储结构,只能顺序操作链表中元素。不,只能顺序操作链表中元素。不能像顺序表(数组)那样可以按下标能像顺序表(数组)那样可以按下标随机随机存取。存取。 在链表存储结构中,不
6、要求存储空间的连续性,数据元素之间在链表存储结构中,不要求存储空间的连续性,数据元素之间的逻辑关系由指针来确定。的逻辑关系由指针来确定。每个结点由两部分组成:data 数据域存放数据值next指针域存放后继结点的首地址链表通过每个指针域将n个结点按逻辑次序链接成一个整体。&b&b&c&c&d&dHead&a&a头指针结点&b&b&c&c&a&a&datanext表头的地址由head指针提供,表尾结点没有直接后继,其指针域应为空指针,指针域为NULL单向链表单向链表 在图所示的
7、链表中,每个结点只有一个指向后继的指针。在图所示的链表中,每个结点只有一个指向后继的指针。也就是说访问数据元素只能由链表头依次到链表尾,而不能做也就是说访问数据元素只能由链表头依次到链表尾,而不能做逆向访问。称这种链表为单向链表或线性链表。这是一种最简逆向访问。称这种链表为单向链表或线性链表。这是一种最简单的链表。单的链表。 对于空链表,头结点的指针域为空。对于空链表,头结点的指针域为空。图图2-8(a)为带头结点的空链为带头结点的空链 (b)为带头结点的单链表为带头结点的单链表headheada1a2a3(a) 空 链 表( b) 非 空 链 表定义链表结点结构的一般形式为Struct 结构
8、体名 数据成员表; 结构体名 *指针变量名;struct studentint num;float score;student *next;struct ListNode ELEM data; ListNode *next;1672873 79486headtail/建立链表linklist *create()linklist *head,*p1,*p2;head=NULL; int x;cinx;struct linklistint num;float score;linklist *next;p2=p1; /将新的结点作为尾结点p2-next=NULL;cinx;while(x0)p1=n
9、ew(linklist);p1-num=x;cinp1-score; n=n+1;if(head=NULL)head=p1;else p2-next=p1;&p1p2p2p1p1如果是首结点呢?定义一个新结点p p2 2return head;建立链表的条件void print( ) coutnendl;/链表输出链表输出形参是什么?需要知道链表的头指针linklist *head如何查找链表?定义一个指针linklist *p1;p1=head;if(head!=NULL)docoutnum score;coutnext;while (p1!=NULL);查找运算查找运算 的实现的实
10、现 设计思路:设置一个跟踪链表结点的指针设计思路:设置一个跟踪链表结点的指针p1,初始,初始时时p1指向链表中的第一个结点,然后顺着指向链表中的第一个结点,然后顺着next域依次域依次指向每个结点,每指向一个结点就判断其值是否等于指向每个结点,每指向一个结点就判断其值是否等于i,若是则返回该结点地址若是则返回该结点地址,否则继续往后搜索否则继续往后搜索.要访问单链表中第要访问单链表中第i个元素值,必须从头指针开始遍历链表,个元素值,必须从头指针开始遍历链表,依次访问每个结点,直到访问到第依次访问每个结点,直到访问到第i个结点为止。其时个结点为止。其时间复杂度为间复杂度为O(n)。 linkli
11、st *getnode else coutinum!=i&p1-next!=NULL) p1=p1-next;j+; 如果该结点不是要找的结点?if(p1-num=i) j+;coutthe node isjendl;return p1;如果该结点是要找的结点?linklist *del(linklist *head, int num)linklist *p1,*p2;if(head!=NULL) p1=head; else coutnextP1-next删除条件if(p1-num=num) if(p1=head)head=p1-next;elsep2-next=p1-next;n=n
12、-1; else coutnumnextP1-nextwhile(p1-num!=num&p1-next!=NULL) p2=p1;p1=p1-next; 如果该结点不是要找的结点?找到该结点如何删除?线性链表的插入:在链式存储结构下的线性表中插入一个新结点线性链表的插入:在链式存储结构下的线性表中插入一个新结点在头指针head的线性链表中包含元素x的结点之前加入一个新结点void inslst(linklist *head, int x)linklist *p1,*p2;p1=new(linklist);cinp1-nump1-score;if(head=NULL)head=p1;p
13、1-next=NULL;p2=getnode(head,x);/寻找包含元素x的结点nextnextnextnextp1p1P2-nextP2-nextp2p2p1-next=p2-next;/将结点p1插入到结点p2后p2-next=p1;在插入和删除算法中,都是先查询确定操作位置,然在插入和删除算法中,都是先查询确定操作位置,然后再进行插入和删除操作。所以其时间复杂度均为后再进行插入和删除操作。所以其时间复杂度均为O(n)。另外在算法中实行插入和删除操作时没有移另外在算法中实行插入和删除操作时没有移动元素的位置,只是修改了指针的指向,所以采用链动元素的位置,只是修改了指针的指向,所以采用链
14、表存储方式要比顺序存储方式的效率高表存储方式要比顺序存储方式的效率高循环链表循环链表循环链表是单链表的另一种形式,是一个首尾相接的链表。特点:最后一个结点的指针域不空,而是指向头结点,整个链表连成环状,从表中任意结点出发均可到达其他结点。&b&b&c&c&d&d&b&b&c&cheadhead&b&b&c&c&d&dhead&b&b&c&cheadheadheadheadhead空循环链表判断表空的条件:head-next=head判断
15、指针指向结点为表尾结点的条件:p-next=head 带头结点的单循环链表的操作算法和带头结点的单链表的带头结点的单循环链表的操作算法和带头结点的单链表的操作算法很相似,差别仅在于算法中的循环条件不同。在循环操作算法很相似,差别仅在于算法中的循环条件不同。在循环单链表上实现上述基本运算的改动如下:单链表上实现上述基本运算的改动如下: 1初始化链表初始化链表initlist(head)创建的头结点指针域创建的头结点指针域next不为空,而是指向自身不为空,而是指向自身head-next=head2线性表查找运算线性表查找运算*getnode(linklist *head, int i)函数函数、
16、链、链表元素输出运算表元素输出运算print(linklist *head)函数中,循环遍历是否进函数中,循环遍历是否进行的条件由行的条件由p!=NULL改为改为p!=head;其余函数运算没有变化,请自行写出相关函数的定义。其余函数运算没有变化,请自行写出相关函数的定义。在循环链表中,除了有头指针在循环链表中,除了有头指针head外,有时还可加上一个尾指针外,有时还可加上一个尾指针tail。尾指针尾指针tail指向最后一结点,沿最后一个结点的指针又可指向最后一结点,沿最后一个结点的指针又可立即找到链表的第一个结点。在实际应用中,使用尾指针来代替立即找到链表的第一个结点。在实际应用中,使用尾指
17、针来代替头指针进行某些操作往往会更简单。头指针进行某些操作往往会更简单。【例例】将两个循环链表首尾相接进行合并,将两个循环链表首尾相接进行合并,La为第一个循环链表表尾为第一个循环链表表尾指针,指针,Lb为第二个循环链表表尾指针,合并后为第二个循环链表表尾指针,合并后Lb为新链表的尾为新链表的尾指针,指针,head指向整个合并后的链表。指向整个合并后的链表。【解解】算法思路:算法思路: 对两个单循环链表对两个单循环链表La,Lb进行的连接操作,是将进行的连接操作,是将Lb的第一个数的第一个数据结点接到据结点接到La的尾部。操作时需要从的尾部。操作时需要从La的头指针开始找到的头指针开始找到La
18、的的尾结点,其时间复杂性为尾结点,其时间复杂性为O(n)。而在循环链表中若采用尾指针而在循环链表中若采用尾指针La,Lb来标识,则时间性能将变为来标识,则时间性能将变为O(1)。其连接过程如图其连接过程如图2-14所示。所示。图图 两个循环链表首尾相接进行合并两个循环链表首尾相接进行合并 (a)(a)连接前连接前p=La-p=La-next;qnext;q=Lb-next=Lb-next(b)连接后连接后La-next=La-next=q;Lbq;Lb-next=p-next=p; ;.a1a2aian.b1b2bibnLaLbpqLbLa.a1a2aian.b1b2bibn双向链表双向链表n
19、extnextdatapriorprior双向链表的结点结构struct dlnode ELEM data; dlnode *next, *prior;对结点p而言,后继结点的地址p-next;前驱结点的地址p-priordatapp1p0P-prior-nextP-next-priorP-priorP-nextsp1p0P1-prior-next=sP1-prior=ss-prior=p1-priors-next=p1双向链表中结点的插入将结点s的插入结点p1之前pP-nextP-prior双向链表中结点的删除P-prior-next=p-nextP-next-prior=p-priorde
20、lete P应用举例应用举例 一元多项式相加一元多项式相加 假设用单链表表示多项式:假设用单链表表示多项式:A(x)=12+7x+8x10+5x17 ,B(x)=8x+15x7-6x10,头指针头指针Ah与与Bh分别指向这两个链表,分别指向这两个链表,如图如图2-21所示:所示: 对两个多项式进行相加运算,其结果为对两个多项式进行相加运算,其结果为C(x)= 12+15x+15 x7+2x10+5x17。如图所示。如图所示。图图 合并以前的链表合并以前的链表 图图 2-22 合并以后的链表合并以后的链表8115 760Bh12 0718105 17Ah15 115 72 105 17012Ch
21、 对两个一元多项式进行相加操作的运算规则是:假设指针对两个一元多项式进行相加操作的运算规则是:假设指针qa和和qb分别指向多项式分别指向多项式A(x)和和B(x)中当前进行比较的某个结点,中当前进行比较的某个结点,则需比较两个结点数据域的指数项,有三种情况:则需比较两个结点数据域的指数项,有三种情况:(1) 指针指针qa所指结点的指数值指针所指结点的指数值指针qb所指结点的指数值时,则保所指结点的指数值时,则保留留qa指针所指向的结点,指针所指向的结点,qa指针后移;指针后移;(2) 指针指针qa所指结点的指数值指针所指结点的指数值指针qb所指结点的指数值时,则将所指结点的指数值时,则将qb指
22、针所指向的结点插入到指针所指向的结点插入到qa所指结点前,所指结点前,qb指针后移;指针后移;(3) 指针指针qa所指结点的指数值指针所指结点的指数值指针qb所指结点的指数值时,将两所指结点的指数值时,将两个结点中的系数相加。若和不为零,则修改个结点中的系数相加。若和不为零,则修改qa所指结点的系数值,所指结点的系数值,同时释放同时释放qb所指结点;反之,从多项式所指结点;反之,从多项式A (x)的链表中删除相应的链表中删除相应结点,并释放指针结点,并释放指针qa和和qb所指结点。所指结点。多项式相加算法:多项式相加算法:struct polynode *add_poly(polynode *
23、Ah, polynode *Bh)polynode *qa,*qb,*s,*r,*Ch;qa=Ah;qb=Bh; /qa和和qb分别指向两个链表的第一结点分别指向两个链表的第一结点r=qa;Ch=Ah;/将链表将链表Ah作为相加后的结果链表作为相加后的结果链表while(qa!=NULL&qb!=NULL) /两链表均非空两链表均非空 if(qa-exp=qb-exp) /两者指数值相等两者指数值相等 x=qa-coef+qb-coef; if(x!=0) qa-coef=x;r-next=qa;r=qa; s=qb+;free(s);qa+; /相加后系数不为零时相加后系数不为零时
24、elses=qa+;free(s);s=qb+;free(s); /相加后系数为零时相加后系数为零时 else if(qa-expexp) r-next=qa;r=qa;qa+; /多项式多项式Ah的指数值小的指数值小 elser-next=qb;r=qb;qb+;/多项式多项式Bh的指数值小的指数值小 链栈链栈toptop栈顶链表的头部作栈顶是最方便的链表的头指针叫做栈顶指针只允许在表头进行插入和删除运算struct linkstackint num;float score;linkstack *next;/置空栈linkstack *init_linkstack()return NULL;
25、/判断栈空int empty_linkstack(linkstack *top)if(top=NULL) return 1;else return 0;/入栈linkstack *push_linkstack(linkstack *top, linkstack *stud)stud-next=top;top=stud;n=n+1;return top;toptopstudstudtoptoptoptop/出栈linkstack *pop_linkstack(linkstack *top, linkstack *stud)if(top=NULL) return NULL;elsestud=top
26、;top=top-next;n=n-1;return top;toptoptoptopstudstud带链的队列带链的队列rearrearfrontfront先进先出的数据结构只允许在表头删除,表尾插入的单链表struct qnodeint num;struct qnode *next;struct lqueueqnode *front,*rear;lqueue *init_lqueue()lqueue *l;qnode *q;l=new(lqueue);q=new(qnode);q-next=NULL;l-front=l-rear=q;return l;创建一个空队列frontrearnex
27、tnextstruct qnodeint num;struct qnode *next;struct lqueueqnode *front,*rear;void in_lqueue(lqueue *l, qnode *q)q-next=NULL;/入队frontrearnextnextnextnext只能在表尾插入结点l-rear-next=q;队尾结点的指针域指向新结点l-rear=q;rear存入新结点地址/出队删除表头结点frontrearnextnextnextnextnextnextqnode *out_lqueue(lqueue *l,) qnode *qreturn q;判断队空的条件i
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安全监控系统值机人员、维护人员职责
- 2024年陕西客运员证是考什么内容
- 2024年福州客运从业资格证考试试题库及答案解析
- 2024年浙江客运资格证考几个科目
- 2024年鹤岗申请客运从业资格证版试题
- 2024年江苏客运资格证急救止血法
- 2024年葫芦岛客运从业资格证理论考试答案
- 2024年山西客运从业资格证试题下载
- 物理-浙江省湖州、衢州、丽水2024年11月三地市高三教学质量检测试卷试题和答案
- 吉首大学《环境保护法学》2021-2022学年期末试卷
- 简单电路实验报告单
- 2023年版一级建造师-水利工程实务电子教材
- 02S701砖砌化粪池标准图集
- 新生儿窒息复苏抢救流程演练
- 医疗设备售后服务方案
- 三重一大决策管理细则
- 项目管理 项目管理
- 问题研究 能否淡化海水解决环渤海地区淡水短缺问题
- GB/T 3634.2-2011氢气第2部分:纯氢、高纯氢和超纯氢
- GB/T 3354-1999定向纤维增强塑料拉伸性能试验方法
- 儿童感觉统合能力发展评定量表含原始分与实用标准分转换表
评论
0/150
提交评论