本文接上一篇队列文章
三、循环队列
循环队列的优点
- 普通队列出队操作开销大:在出队操作时,索引为
0
后面的所有元素,都需要往前移动一位,元素越多,消耗的时间也越多,时间复杂度为O(N)
3.1 循环队列的逻辑
- 当元素较少时(
tail
位置在front
后面),循环队列与普通队列出队操作一样,入队的元素将会放在tail
的位置上,随后执行tail++
操作;出队时front
位置上的元素将会置null
,随后执行front++
操作;此时仍能保持着tail
位置在front
后面的状态,如下图所示:
- 当元素继续添加,最后一个元素将放到索引为
7
的位置,此时tail
位置将会移动到队首前面索引为0
的位置上,此时tail
在数组的索引为变为:(tail+ 1 )% capacity
如下图所示:
- 当元素继续添加时,元素将会在
tail
位置上添加,tail
继续往后移动,如下图所示:
- 继续添加元素,当
tail
与front
还相距一个单位时,即此时数组还有一个空余存储空间,但当前数组已经不能继续实现循环队列的插入操作了,因为循环队列判断队列为空的条件就是front == tail
,所以此时需要进行扩容操作;因此此处有意识的浪费了一个空间。
此处可以推出,循环队列元素满的条件为:tail +1 == front
(初步得出,后续会完善为(tail + 1) % capacity == front
) - 适当情况下,此若时持续进行出队操作,
front
的位置也将会从数组最右端跳转到数组最左端开始。此时front
在数组的索引为变为:(front + 1 )% capacity
3.2 循环队列的结论
- 循环队列:底层也是通过数组来实现,但是它的入队和出队操作,不能使用
Array
中封装的方法,而是需要重新去代码实现; - 通过
front
指向队首的位置,tail
指向下一个元素即将插入的位置,即tail
位置元素始终为null
;
- 循环队列是否为空的条件:
front == tail
; - 循环队列中
tail
位置在数组中对应的索引位置:(tail + 1) % capacity
- 循环队列中
front
位置在数组中对应的索引位置:(front+ 1) % capacity
- 循环队列装满的条件:
(tail + 1) % capacity == front
; 其中capacity
为数组的空间大小;
3.3 循环队列代码实现
代码如下:
package dataStructure.chapter3;
/**
* @Author: zjtMeng
* @Date: 2019/12/28 20:13
* @Version 1.0
*/
public class LoopQueue<E> implements Queue<E> {
private E[] data;
private <