比较普通队列的缺点,用取模的思想将队列设计为类似于“环形”的概念。
生活中的队列
队列,计算机中的一种数据结构,是一种先进先出(FIFO)
的存储结构。类似于生活中排队的场景,先排上的人,先执行。但是本质上还是会有两种区别。
- 比如说,排队打饭和排队点人这两种场景。
- 排队打饭的时候,执行者(打饭阿姨)不动,队列一个一个向前进。
- 排队点人的时候,队列不动,执行者(小组长)一个一个向后数数。
这两种处理方式都没什么效率。
- 第一种
数据移动频繁
,对排队的人和对计算机来说,都是一种负担。 - 第二种
空间占位闲置
,小组长数完前面的人,他们就可以去玩了,但是如果场地不够大,排队的人又很多,前面的位置就闲置了。
像我排队的时候真的懒得动……我希望排队的时候像坐电梯一样自己动。最好是有一个环形的电梯,打完一个转到下一个,然后新来的就找到队伍的末尾,站到电梯上来,同时,这个电梯不需要很多站位,只需要打饭速度和人来的速度差不多,不至于电梯占满了就行,这就解决了空间不够的问题。
环形队列的设计
计算机也是这样,需要考虑效率
和空间
的问题。
- 一个队列相当于一个存储数据的容器,同时它还必须方便插入和取出数据,而队列一般就是一个数组结构,每个位置都有
index
作为下标。- 插入数据就找到上一次插入的
index(tail)
,在下一位将数据放进去; - 读取数据就找到上一次读到的
index(head)
,将下一个数据读取出来(并删除,这是队列的出队)。
- 插入数据就找到上一次插入的
- 按照上面那样的设计,想要让队列在插入的时候,
tail
位置是空的,充分利用数组前面空出来的空间,就需要让tail
在到达index
序号最大值的时候能转回来,从0
重新开始取值。同样的head
也必须能够转回来,这样的设计,更像是一个“圆环”。
- 利用“模”的概念可以实现这样的设计,让
head
和tail
分别对队列容量取模。- 假设队列容量为10
tail
取到9的时候就到队列末尾了- 这个时候再入队,就下标越界了
tail=10
- 我们让
tail
对10
取模,tail
就回到了0
的位置 - 当然必不可少的:入队检查队列未满,出队检查队列非空
这样就可以实现一个环形队列
了。
本文可以参考: