环形队列

比较普通队列的缺点,用取模的思想将队列设计为类似于“环形”的概念。

生活中的队列

队列,计算机中的一种数据结构,是一种先进先出(FIFO)的存储结构。类似于生活中排队的场景,先排上的人,先执行。但是本质上还是会有两种区别。

  • 比如说,排队打饭和排队点人这两种场景。
    • 排队打饭的时候,执行者(打饭阿姨)不动,队列一个一个向前进。
    • 排队点人的时候,队列不动,执行者(小组长)一个一个向后数数。

这两种处理方式都没什么效率。

  • 第一种数据移动频繁,对排队的人和对计算机来说,都是一种负担。
  • 第二种空间占位闲置,小组长数完前面的人,他们就可以去玩了,但是如果场地不够大,排队的人又很多,前面的位置就闲置了。

像我排队的时候真的懒得动……我希望排队的时候像坐电梯一样自己动。最好是有一个环形的电梯,打完一个转到下一个,然后新来的就找到队伍的末尾,站到电梯上来,同时,这个电梯不需要很多站位,只需要打饭速度和人来的速度差不多,不至于电梯占满了就行,这就解决了空间不够的问题。

环形队列的设计

计算机也是这样,需要考虑效率空间的问题。

  • 一个队列相当于一个存储数据的容器,同时它还必须方便插入和取出数据,而队列一般就是一个数组结构,每个位置都有index作为下标。
    • 插入数据就找到上一次插入的index(tail),在下一位将数据放进去;
    • 读取数据就找到上一次读到的index(head),将下一个数据读取出来(并删除,这是队列的出队)。
  • 按照上面那样的设计,想要让队列在插入的时候,tail位置是空的,充分利用数组前面空出来的空间,就需要让tail在到达index序号最大值的时候能转回来,从0重新开始取值。同样的head也必须能够转回来,这样的设计,更像是一个“圆环”。

image

  • 利用“模”的概念可以实现这样的设计,让headtail分别对队列容量取模。
    • 假设队列容量为10
    • tail取到9的时候就到队列末尾了
    • 这个时候再入队,就下标越界了tail=10
    • 我们让tail10取模,tail就回到了0的位置
    • 当然必不可少的:入队检查队列未满,出队检查队列非空

这样就可以实现一个环形队列了。


本文可以参考: