队列的线性实现——循环队列

从上一篇博客说起

之前说过,如果是单纯一个数组就很容易造成假溢出,那么就有人会想到,如果我把一个数组看成是一个环,将最后一个元素和第一个元素连上(实际的存储结构还是数组,这个不可能连上),那么是不是就可以解决假溢出了?

实现

为了出对入队方便,设两个下标(int型)分别指向队头front(第一个元素)和队尾rear(最后一个元素的下一位)。

那么此时有计算公式:
插入:队头不变,rear = (rear+1)%length
删除:队尾不变,front = (front+1)%length

但是,在队列为空的时候,队头队尾的位置是相同的,在队满的时候,也是相同的。

正常存储的案例:(红笔为存储元素的位子)
队列的线性实现——循环队列
队空:

队列的线性实现——循环队列
队满:(这种是一直入队没有出队,有出队rear的位置也会变化)
队列的线性实现——循环队列
(好叭我这个图是真的丑)

解决队空队满一样的方式

1.简单粗暴,用一个bool型或者是int型变量存储队列状态。
如果是插入了之后下标相同,那么一定是队满,如果是删除后相同,则队空。
2.书上给的话是:少用一个位置,在队满的时候队头指针在队尾指针的下一位(沿着循环数组的下一位)
不太好理解,那就上图:
开始的时候同上,两个指针位置都在a[0]处;
因为要保证队满front是rear的下一个,则队列的线性实现——循环队列
因为rear的位置是下一个元素插入的地方,而队满的就应该是这样的,所以a[0]就不能放入
(如果有出队不能放入的就不是a[0]了,而是其他的一个位置)

总结

两种方法其实本质上都消耗了一个位置,以分辨两种情况。
因为还是数组结构,如果在使用前不能确定存储数据的数目,建议试应链表队列。