循环队列判断队空和队满_队列,计算机中的排队模型

生活中随处可见队列,例如食堂打饭,超市买单的时候,我们都会自然而然地排队。那么,在计算机中如何表示这一现象呢?

1.什么是队列

队列,是一种我们再熟悉不过的模型了,现实中到处可见它的场景,比如,饭堂打饭需要排队,购票需要排队。队列是一种最体现公平的数据结构,因为它的特点就是“先进先出(First In First Out,FIFO)”,意思就是,按照来到的先后确定次序,先进入队列的人,最先离开队列。这也是合理的,在饭堂打饭时,自然是先到的人先排队然后打到饭离开。(这里我们不考虑插队这种不文明的现象)

2.入队与出队

a32864b450222cd95cd5ad9432d63e8a.png

ac0b999fef21c0e93f9bf579b1fe9330.png

类似排队模型,上面的图我们能够很快的看懂,60,70,80,90依次到达,那自然是60排在最前面,90排在最后面。出队的话,就是从队头开始出队。跟栈类似,队列也有它独特的操作,入队和出队。

往队列中插入数据的过程,就是入队,在队列中,最新插入的数据排在队尾。

队首从队列中离开的郭恒,就是出队。在队列中,只有队首的数据能够出队。

3.循环队列

队列模型并不难理解,怎么将它在代码中表示呢?能够跟栈一样,用数组来表示呢?假如我们有长度为10的队列,我们用长度为10的数组来表示。

3bea8adde95d35caa43d7d09b33020bd.png

如图所示,确实可以用数组来表示队列,但假如我们做了以下操作:将60出队。这时候,会发生什么事情呢?

d49b4eb90a78b203744ae46caf6f436a.png

可能这时候还看不出什么影响,如果我们再往队列加入100,然后将70出队,就会变成

da125c0548b180935c8710a3cf47438a.png

聪明的读者可能已经发现了,由于队首指针跟队尾指针一直在往前走,A[0]和A[1]的空间被“废弃”了,我们再也用不到它。这样的话这些空间不就被浪费了吗?这样的数据结构有什么办法可以把这些废弃空间也利用起来呢?聪明的计算机科学家们想到了“循环队列”的方法。

循环队列的核心是取余操作,也就是编程中的%。n=10的数组,只要在指针自增1的时候,对n取模,就变成了循环队列。

比如,队尾指针rear指向9的时候,下一个位置是(9+1)%10 = 0,再下一个位置是(0+1)%10=1,对应的公式为(rear+1)%n,

这样指针就会在0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,……之间不停地循环。由于这个操作,前面的例子就可以再次访问到被废弃的A[0],A[1]。

由于指针可以循环了,怎么判断队列为空和满的情况呢?很自然的,我们想到一开始为空的情况,就是队首指针front和队尾指针rear都重叠在起始位置,判断条件也就是front == rear成立的时候为空

1f1bd6102dfb0d76a3245b4c8c6b16bd.png

我们来看看队列满的情况。

d1476c9efee3694484a9c2f92ba799bf.png

如图所示,队尾指针已经快追上队首指针,这时候说明队列已经快存满了。当我们往队列中插入最后一个数据时,会发现,队尾指针跟对队首指针又重叠了。

44655433b37425be1de29283b9449543.png

这时候,又变成了front==rear的情况,跟队列为空时的判断条件相同。这样我们就无法区分队列为空还是满载了。怎么办呢?聪明的科学家们又想到了,只要牺牲一个位置,就可以让队尾指针跟队首指针不重合,从而区分开两种情况。我们看到队满之前的前一张图。

62b0b556d4ce558d011122fff2c34d7b.png

我们认定此时队列已经满了,不能再插入新的数据不就好了吗?此时的判断条件为(rear+1)%n == front,也就是队尾指针再往前一步就跟队首指针重合,此时我们就认为队列已经满了,不能入队,只能出队。

由于队列里面的指针在数组中不停地循环,我们也形象地称之为循环队列。

4.总结

时间复杂度:建队O(n),入队O(1),出队O(1)

特点:先进先出

循环队列队空条件:front == rear

循环队列队满条件:(rear+1)%n == front


公众号:萌凯的程序人生
一枚IT研究生,致力于分享自己的学习经历和总结!
喜欢的话请点赞关注,谢谢您!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值