收藏 分享(赏)

数据结构与算法。第3章 栈和队列(3).ppt

上传人:Facebook 文档编号:2589345 上传时间:2018-09-22 格式:PPT 页数:35 大小:548.50KB
下载 相关 举报
数据结构与算法。第3章 栈和队列(3).ppt_第1页
第1页 / 共35页
数据结构与算法。第3章 栈和队列(3).ppt_第2页
第2页 / 共35页
数据结构与算法。第3章 栈和队列(3).ppt_第3页
第3页 / 共35页
数据结构与算法。第3章 栈和队列(3).ppt_第4页
第4页 / 共35页
数据结构与算法。第3章 栈和队列(3).ppt_第5页
第5页 / 共35页
点击查看更多>>
资源描述

1、2018年9月22日,数据结构讲义,1,从上图所示的循环队可以看出:可见在队满和队空情况下都有:front=rear, 这显然是必须要解决的一个问题。,方法之一是:附设一个存储队中元素个数的变量如num,当num=0时队空,当num=MAXSIZE时为队满。 另一种方法是:少用一个元素空间,把图(d)所示的情况就视为队满,此时的状态是队尾指针加1就会从后面赶上队头指针,这种情况下队满的条件是:(rear+1) % MAXSIZE =front,也能和空队区别开。我们采用第一种方法。,2018年9月22日,数据结构讲义,2,循环队列的类型定义如下:typedef struct datatype

2、dataMAXSIZE; /*数据的存储区*/int front,rear; /*队头队尾指针*/int num; /*队中元素的个数*/CSeQueue; /*循环队*/,2018年9月22日,数据结构讲义,3, 置空队【算法3-14】构建一个空的循环队算法 CSeQueue* Init_SeQueue() CSeQueue *q;q=(CSeQueue *)malloc(sizeof(CSeQueue);qfront=qrear=MAXSIZE-1;qnum=0;return q;,2018年9月22日,数据结构讲义,4, 入队 【算法3-15】循环队入队算法int In_SeQueue

3、( CSeQueue *q , datatype x) if(qnum=MAXSIZE) printf(“队满“);return -1; /*队满不能入队*/else q-rear=(qrear+1) % MAXSIZE;qdataqrear=x;qnum+;return 1; /*入队完成*/,2018年9月22日,数据结构讲义,5, 出队 【算法3-16】循环队出队算法int Out_SeQueue (CSeQueue *q, datatype *x)if (qnum=0) printf(“队空“);return -1; /*队空不能出队*/else qfront=(qfront+1) %

4、 MAXSIZE;*x=qdataqfront; /*读出队头元素*/qnum-; return 1; /*出队完成*/,2018年9月22日,数据结构讲义,6, 判队空【算法3-17】判循环队空队算法 int Empty_SeQueue(CSeQueue *q) if (qnum=0) return 1;else return 0;,2018年9月22日,数据结构讲义,7,链队链式存储的队称为链队。和链栈类似,用单链表来实现链队,根据队的FIFO原则,为了操作上的方便,我们分别需要一个头指针和尾指针,如图所示。 图中头指针front和尾指针rear是两个独立的指针变量,从结构性上考虑,通常将

5、二者封装在一个结构中。,2018年9月22日,数据结构讲义,8,链队的描述如下: typedef struct node datatype data;struct node *next;QNode; /*链队结点的类型*/typedef struct QNnode *front,*rear;LQueue; /*将头尾指针封装在一起的链队*/ 定义一个指向链队的指针:LQueue *q;,2018年9月22日,数据结构讲义,9,带头结点的链队如图所示:,2018年9月22日,数据结构讲义,10,(1) 创建一个带头结点的空队 【算法3-18】置一个空链队算法LQueue *Init_LQueue

6、() LQueue *q;Qnode *p;q=(LQueue *)malloc(sizeof(LQueue); /*申请头尾指针结点*/p=(QNode *) malloc(sizeof(QNode); /*申请链队头结点*/pnext=NULL; qfront=p;qrear=p;return q;,2018年9月22日,数据结构讲义,11,(2)入队 【算法3-19】链队入队算法void In_LQueue(LQueue *q , datatype x) QNode *p;p=(QNode *)malloc(sizeof(QNode); pdata=x; pnext=NULL;qrear

7、next=p;qrear=p;,2018年9月22日,数据结构讲义,12,(3) 判队空【算法3-20】判链队空算法int Empty_LQueue(LQueue *q) if (qfront=qrear) return 1;else return 0;,2018年9月22日,数据结构讲义,13,(4) 出队 【算法3-21】链队出队算法int Out_LQueue(LQueue *q, datatype *x) QNode *p;if (Empty_LQueue(q) ) printf (“队空“); return 0; /*队空,出队失败*/ else p=qfrontnext;qfron

8、tnext=pnext;*x=pdata; /*队头元素放x中*/free(p);if (qfrontnext=NULL)qrear=qfront; /*只有一个元素时,出队后队空,此时还要要修改队尾指针*/return 1;,2018年9月22日,数据结构讲义,14,队列是一种应用广泛的数据结构,凡具有“先进先出”需要排队处理的问题,都可以使用队列来解决。 1. 队列在输入、输出管理中的应用在计算机进行数据输入、输出处理时,由于外部设备的速度远远低于CPU数据处理的速度,此时可以设定一个“队列缓冲区”进行缓冲。当计算机要输出数据时,将计算机的数据按块(例如每块512B)逐个添加到“队列缓冲区

9、”的尾端,而外部设备则按照其输出速度从队首逐个取出数据块输出。这样,虽然输出数据速度较慢,但却能保证与计算机输出的数据有完全相同的次序,而不致发生输出次序的混乱或数据的丢失。,3.4 队列应用举例,2018年9月22日,数据结构讲义,15,2.对CPU的分配管理一般的计算机系统只有一个CPU,如果在系统中有多个进程都满足运行条件,可以用一个就绪队列来进行管理。当某个进程需要运行时,它的进程名就被插入到就绪队列的尾端。CPU总是首先执行排在队首的进程,一个进程分配的一段时间执行完了,又将它插入到队尾等待。如此,按“先进先出”的原则一直进行下去,直到执行完的进程从队列中逐个删除掉。,2018年9月

10、22日,数据结构讲义,16,3.4 队列应用举例,例3-5 设计一个算法找一条从迷宫入口到出口的最短路径。算法的基本思想为:从迷宫入口点(1,1)出发,向四周搜索,记下所有一步能到达的坐标点;然后依次再从这些点出发,再记下所有一步能到达的坐标点,依此类推,直到到达迷宫的出口点(m,n)为止,然后从出口点沿搜索路径回溯直至入口。这样就找到了一条迷宫的最短路径,否则迷宫无路。,2018年9月22日,数据结构讲义,17,有关迷宫的数据结构、试探方向、如何防止重复到达某点以避免发生死循环的问题与例3.2处理相同,不同的是:如何存储搜索路径。 在搜索过程中必须记下每一个可到达的坐标点,以便从这些点出发继

11、续向四周搜索。由于先到达的点先向下搜索,故引进一个队列来保存已到达的坐标点。,2018年9月22日,数据结构讲义,18,到达迷宫的出口点(m,n)后,为了能够从出口点沿搜索路径回溯直至入口,对于每一点,记下坐标点的同时,还要记下到达该点的前驱点,用一个结构数组sqnum作为队列的存储空间。sq的每一个结构有三个域:x,y和pre。其中x,y分别为所到达的点的坐标,pre为前驱点在sq中的坐标,还有队头、队尾指针。,队的定义如下: typedef struct int x,y;int pre;sqtype; sqtype sqnum; int front,rear;,2018年9月22日,数据结

12、构讲义,19,初始状态:队列中只有一个元素sq1记录的是入口点的坐标(1,1),因为该点是出发点,因此没有前驱点,pre域为-1,队头指针front和队尾指针rear均指向它。此后搜索时都是以front所指点为搜索的出发点,当搜索到一个可到达点时,即将该点的坐标及front所指点的位置入队,不但记下了到达点的坐标,还记下它的前驱点。front所指点的个方向搜索完毕后,则出队,继续对下一点搜索。搜索过程中遇到出口点则成功,搜索结束,打印出迷宫最短路径,算法结束;或者当前队空即没有搜索点了,表明没有路径算法也结束。,2018年9月22日,数据结构讲义,20,算法描述,入口点入队 标记入口点为已到达

13、 while 队列不空:队头元素front出队对与front相邻的每个点:如果该点可达:将该点坐标及其前驱点front入队标记该点为已到达如果该点是出口点:打印路径;结束,算法示例,2018年9月22日,数据结构讲义,21,入口点入队 标记入口点为已到达 while 队列不空:队头元素front出队对与front相邻的每个点:如果该点可达:将该点坐标及其前驱点front入队标记该点为已到达如果该点是出口点:打印路径;结束,2018年9月22日,数据结构讲义,22,入口点入队 标记入口点为已到达 while 队列不空:队头元素front出队对与front相邻的每个点:如果该点可达:将该点坐标及其

14、前驱点front入队标记该点为已到达如果该点是出口点:打印路径;结束,void path (int mazemn; item move8) SqType sqNUM;sq0.x=1; sq0.y=1; sq0.pre=-1; front=rear=0; maze1,1=-1;while (front=rear) /*队列不空*/ x=sqfront+.x ; y=sqfront+.y;for (v=0;v8;v+) i=x+movev.x; j=x+movev.y;if (mazeij=0) rear+;sqrear.x=i; sqrear.y=j; sqrear.pre=front;maze

15、ij=-1; if (i=m ,2018年9月22日,数据结构讲义,23,入口点入队 标记入口点为已到达 while 队列不空:队头元素front出队对与front相邻的每个点:如果该点可达:将该点坐标及其前驱点front入队标记该点为已到达如果该点是出口点:打印路径;结束,void path (int mazemn; item move8) SqType sqNUM;sq0.x=1; sq0.y=1; sq0.pre=-1; front=rear=0; maze1,1=-1;while (front=rear) /*队列不空*/ x=sqfront+.x ; y=sqfront+.y;for

16、 (v=0;v8;v+) i=x+movev.x; j=x+movev.y;if (mazeij=0) rear+;sqrear.x=i; sqrear.y=j; sqrear.pre=front;mazeij=-1; if (i=m ,2018年9月22日,数据结构讲义,24,入口点入队 标记入口点为已到达 while 队列不空:队头元素front出队对与front相邻的每个点:如果该点可达:将该点坐标及其前驱点front入队标记该点为已到达如果该点是出口点:打印路径;结束,void path (int mazemn; item move8) SqType sqNUM;sq0.x=1; sq

17、0.y=1; sq0.pre=-1; front=rear=0; maze1,1=-1;while (front=rear) /*队列不空*/ x=sqfront+.x ; y=sqfront+.y;for (v=0;v8;v+) i=x+movev.x; j=x+movev.y;if (mazeij=0) rear+;sqrear.x=i; sqrear.y=j; sqrear.pre=front;mazeij=-1; if (i=m ,2018年9月22日,数据结构讲义,25,入口点入队 标记入口点为已到达 while 队列不空:队头元素front出队对与front相邻的每个点:如果该点可

18、达:将该点坐标及其前驱点front入队标记该点为已到达如果该点是出口点:打印路径;结束,void path (int mazemn; item move8) SqType sqNUM;sq0.x=1; sq0.y=1; sq0.pre=-1; front=rear=0; maze1,1=-1;while (front=rear) /*队列不空*/ x=sqfront+.x ; y=sqfront+.y;for (v=0;v8;v+) i=x+movev.x; j=x+movev.y;if (mazeij=0) rear+;sqrear.x=i; sqrear.y=j; sqrear.pre=f

19、ront;mazeij=-1; if (i=m ,2018年9月22日,数据结构讲义,26,入口点入队 标记入口点为已到达 while 队列不空:队头元素front出队对与front相邻的每个点:如果该点可达:将该点坐标及其前驱点front入队标记该点为已到达如果该点是出口点:打印路径;结束,void path (int mazemn; item move8) SqType sqNUM;sq0.x=1; sq0.y=1; sq0.pre=-1; front=rear=0; maze1,1=-1;while (front=rear) /*队列不空*/ x=sqfront+.x ; y=sqfro

20、nt+.y;for (v=0;v8;v+) i=x+movev.x; j=x+movev.y;if (mazeij=0) rear+;sqrear.x=i; sqrear.y=j; sqrear.pre=front;mazeij=-1; if (i=m ,2018年9月22日,数据结构讲义,27,入口点入队 标记入口点为已到达 while 队列不空:队头元素front出队对与front相邻的每个点:如果该点可达:将该点坐标及其前驱点front入队标记该点为已到达如果该点是出口点:打印路径;结束,void path (int mazemn; item move8) SqType sqNUM;sq

21、0.x=1; sq0.y=1; sq0.pre=-1; front=rear=0; maze1,1=-1;while (front=rear) /*队列不空*/ x=sqfront+.x ; y=sqfront+.y;for (v=0;v8;v+) i=x+movev.x; j=x+movev.y;if (mazeij=0) rear+;sqrear.x=i; sqrear.y=j; sqrear.pre=front;mazeij=-1; if (i=m ,思考,需要初始化多大的队列? 迷宫最短路算法的复杂度是多少?,2018年9月22日,数据结构讲义,28,DFS vs BFS,深度优先搜索

22、 “一条道走到黑”、 “不撞南墙不回头”广度优先搜索 “多而杂”、 “浅尝辄止”,2018年9月22日,数据结构讲义,29,2018年9月22日,数据结构讲义,30,3.5 小结1.栈和队列是在软件设计中常用的两种数据结构,它们的逻辑结构和线性表相同。其特点在于运算受到了限制:栈按“后进先出”的规则进行操作,队按“先进先出”的规则进行操作,故称它们为运算受限制的线性表。2.和线性结构类似,栈和队列也有顺序和链式两种存储结构。本章介绍了顺序栈、链栈、顺序队(循环队)、链队的表示及相关的操作。3.在顺序存储情况下,入栈和入队时要判断是否栈满和队列满,如果已满,则表明设计的空间不够,不能入栈和入队;

23、而栈空和队列空经常用来作为控制结束的条件。,2018年9月22日,数据结构讲义,31,作业,用队列的基本运算改写迷宫最短路算法 教材第3章习题 四-3,2018年9月22日,数据结构讲义,32,实验1:算术表达式求值,输入 中缀表达式字符序列 例:12/(9*(3+5) 输出 求值过程:每一步读入的字符和对象栈、运算符栈的变化情况 最终结果 在读入表达式字符序列的同时,完成对运算符和运算对象的识别和处理。对运算对象要将其字符形式转换成整数形式,再进行相应的运算 用程序实现运算符优先级比较 健壮性:程序能检测非法表达式输入并作出恰当处理,2018年9月22日,数据结构讲义,33,实验2:求迷宫最短路径,输入 迷宫、入口坐标、出口坐标(从文件读入) 输出 用队列搜索路径的过程和队列的变化情况 找到的最短路径 和用栈求解迷宫作比较,用实际的运行结果数据分析比较二者的算法复杂度和各自特点,2018年9月22日,数据结构讲义,34,要求,选做(有加分) 分组:12人 提交 实验报告 源程序 课堂讲解和演示 截止时间 11月26日,2018年9月22日,数据结构讲义,35,大实验,实验报告和课堂讲解要求 输入输出的设计和实现 程序健壮性设计和实现(实验1) 算法对比和分析(实验2) 遇到的问题和解决方法 加分 要求:独立完成、程序能跑 依据:选题、完成情况、分组人数,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 中等教育 > 小学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报