《大话数据结构》

循环队列定义


所以解决假溢出的办法就是后面满了,就再从头开始,也就是头尾相接的循环。我们把队列的这种头尾相接的顺序存储结构称为循环队列。
刚才的例子继续,图 4 12 5 的rear可以改为指向下标为0的位置,这样就会造成指针指向不明的问题了,如图 4 12 6所示、


接着入队a 6,将他/它放置于下表为0处,rear 指针指向下表为1处,如图 4 12 7的左图所示、若再入队a 7 ,则rear 指针就与front指针重合,同时指向下表为2的位置,如图 4 12 7的右图所示。


此时问题又出来了,我们刚才说,空队列时,fro nt等于rear,现在当队列满时,也是front等于:ear ,那么如何判断此时的队列究竟是空还是满呢?办法一是没置一个标志变啧t1a},’当front=二,ear,且flab=l3时为队列空,当front == rear,且fl a} =,时为队列满。办法二是当队列空时,条件就是front=rear,当队列满时,我们修改其条件,保留一个元素空lb]。也就是说,队列满时,数组中还有一个空闲单元。例如图4-12-8所示,我们就认为此队列已经满了,也就是说,我们不允许图 4 12 7的右图情况出现、



我们重点来讨沦第二种方法,由十rear可能比front大,也可能比Front小,所以尽管它们只相差一个位置时就是满的情况,但也可能是相差整整一圈。所以若队列的最大尺寸为QueueSiae,那么队列满的条件是(rear+l)%QueueSiae == front(取模“%”的日的就是为了整合rear与front大小为一个问题)。比如上面这个例子,QueueSiae==5,图}-12-8的左图中front=d,而rear=4,列满。一再比如图4-12-8中的右图,front二2而rear = 1 a队列也是满的口而对于图4-12-6,front二2而rear二。,此时队列并没有满。[ 4+15 aln5二U,所以此时队  (1十1) 01a 5二2,所以此时(8+1) 0/a5二1,1 } 2,所以另外,当rear》front时,即图 4 12 4的右图和 4 12 5的左图,此时队列的长度为rear-front。但当rear } front时,如图 4 12 6和图 4 12 7的左图,队列长度分为}7 }、一段是QueueSize一front,另一段是O+rear,加在一起,队列长度为rear一front f QueueSixe4因此通用的计算队列长度公式为:(rear一front+QueueSiaey 0YoQueueSixe有了这些讲解,现在实现循环队列的代码就不难了。


队伍的链式存储结构及实现


队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链队列。为了操作土的方便,我们将队头指全十指向链队列的头结点,而队尾指针指向终端结点,如下图所示。


空队列时, front 和 rear 都指向头结点,如下图所示。


队列的链式存储结构·····入队操作


入队操作时,其实就是在链表尾部插人结点,如图下图所示


从这一段讲解,大家应该发现,单是顺序存储,若不是循环队列,算法的时I}} r能是不高的,但循环队列又面临着数组可能会溢出的间题,所以我们还需要研究一下不需要担心队列长度的链式存储结构。


队列的链式存储结构·····出队操作


出队操作时,就是头结点的后继结点出队,将头结点的后继改为它后面的结点,若链表除头结点外只剩一个元素时,则需将rear指向头结点,如下图所示。



对于循环队列与链队列的比较,可以从两方面来考虑,从时间上,其实它们的基本操作都是常数时间,即都为。[1]的,不过循环队列是事先申请好空间,使用期i}}不释放,而对T链队列,海次中请和释放结点也会存在一些时间开销,如果人队出队频繁,则两者还是有细微差异。对于空间上来说,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链队列不存在这个问题,尽管它需要一个指针域,会产牛一些空间上的开销,但也可以接受。所以在空间上,链队列更加灵活。总的来说,在可以确定队列长度最大值的情况卜,建议用循环队列,如果你无法预估队列的长度时,则用链队列。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值