西安电子科技大学数据结构C语言版第3章.ppt

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
西安电子科技大学数据结构C语言版第3章

图3.11 队列 在日常生活中队列的例子到处皆是,如等待购物的顾客总是按先来后到的次序排成队列,先得到服务的顾客是站在队头的先来者,而后到的人总是排在队的末尾。还有航空订票系统、宾馆客房预定系统等等都用到队列数据结构。 队列的运算可以归纳为以下几种: (1) AddQ(Q,x): 在队列的尾部插入一新元素x。队尾的位置由rear指出。 (2) DelQ(Q): 删除队列的队头元素。队头的位置由front指出。 (3) EmptyQ(Q): 测试队列Q是否为空。队列为空时返回真值,否则返回假值。 (4) FrontQ(Q): 取得队列Q的队头元素。 (5) SetNULL(Q): 创建一个空队Q,这个运算与线性表置空表类似。 3.2.2 队列的顺序存储结构 队列的顺序存储结构和栈类似。在计算机中,常借助于一维数组来存储队列中的元素。为了指示队首和队尾的位置,尚需设置头、尾两个指针,并约定头指针总是指向队列中实际队头元素的前面一个位置,而尾指针总是指向队尾元素。详见图3.12。 图3.12 队列顺序存储结构 顺序存储结构描述是: typedef struct { ElemType elem[MAXSIZE]; int front,rear; } SeQueue; SeQueue Q; 图3.13是能容纳6个元素的队列在运算过程中头尾指针的变化示意图。其中图(a)表示该队列的初始状态为空,Q.rear=Q.front=-1;图(b)表示有3个元素a1、a2、a3相继入队列,因而Q.rear=2,而Q.front的值不变;图(c)表示a1、a2、a3先后出队,队列又变为空,Q.rear=Q.front=2;图(d)表示3个元素a4、a5、a6进入队列,Q.front=2,Q.rear=5。 图3.13 一个队列中元素和头尾指针的关系 假若还有元素a7请求进入队列,由于队尾指针已经指向了队列的最后一个位置,因此插入a7就会发生“溢出”。但是,这时的队列并非真正满了,事实上队列中尚有3个空位。也就是说,系统作为队列用的存储区还没有满,但队列却发生了溢出,我们把这种现象称为“假溢出”。解决“假溢出”的方法有两种: (1) 采用平移元素的方法,即一旦发生“假溢出”就把整个队列的元素平移到存储区的首部。如图3.14所示,将a4、a5、a6平移到Q.elem[0]至Q.elem[2],而将a7插到第3个位置上,显然,平移元素的方法效率是很低的。 图3.14 用平移元素的方法克服假溢出 (2) 将整个队列作为循环队列来处理。我们可以设想,Q.elem[0]接在Q.elem[5]之后,如图3.15(a)所示,当发生假溢出时,可以把a7插入到第0个位置上。这样,虽然物理上队尾在队首之前,但逻辑上队首仍然在前,作插入和删除运算时仍按“先进先出”的原则。 图3.15(b)展示了元素a8和a9进入队列后的情形。此时队列已满,如果还要插入元素就会发生上溢。而它与图3.15(c)所示队列为空的情形一样均出现头指针等于尾指针的情况,即Q.front==Q.rear。 图3.15 用循环队列的方法克服假溢出 由此可见,在循环队列中只凭等式Q.rear==Q.front无法判别队空还是队满。因此,可再设置一个布尔变量来区分队空和队满;或者不设布尔变量,而把尾指针加1后是否等于头指针,作为判断队满的标志。这意味着损失一个空间,或者反过来说,如果数组拥有MAXSIZE+1个元素,那么只能表示一个长度为MAXSIZE-1的循环队列。以上两种方法都要多占存储空间,但后者比较节省时间。此时空队列条件仍为Q.front==Q.rear,而队满条件则是(Q.rear+1)%MAXSIZE==Q.front,详细见图3.15(d)。 在循环队列中每插入一个新元素就把尾指针沿顺时针方向移动一个位置,即: Q.rear=(Q.rear+1) % MAXSIZE; Q.elem[Q.rear]=x; 同样,每删除一个新元素就把头指针沿顺时针方向移动一个位置,即: Q.front=(Q.front+1) % MAXSIZE; 下面给出循环队列主要操作的算法。 (1) 将循环队列置为空的算法。 void SetNULL(SeQueue *Q) { Q-front=-1; Q-rear=-1; } (2) 判断循环队列是否为空。 int Empty(SeQueue Q)

文档评论(0)

qwd513620855 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档