队列:先进先出,像我们的排队。
循环队列:数组实现,是对数组空间的有效利用
1、初始头部和尾部都指向0处
2、插入的时候rear指针放入插入元素,之后rear指针向后移,也就是说rear指向下一个待插入位置的元素,而front指向第一个元素的位置。
3、当取元素的时候,取出front指针指向的元素,并且front指针后移
4、由于是环形链表,rear和front指针向后移动的时候采用取余操作(rear+1)%maxSize。
5、表空的时候尾rear = front,为了区分表空和表满会空出一个空间进行区分,及当
(rear+1)%maxSize = front的时候为表满。
6、表中数据的个数:令rear-front此时若rear在front之上是正确的数据,但是为循环队列,有可能为负数,rear在front之下,当为负数的时候应该加上maxSize就为当前有效个数,但是正数的时候就多了maxSzie个,此时采用取余操作,所以说,队列的有效个数为:(rear-front+maxSize)%maxSize
==示意图==
==代码实现==
public class LitGrassCircleQueue<T> {
private Object[] elements;
//首节点
private int front;
//尾节点
private int rear;
private int maxSize;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public LitGrassCircleQueue(int initCapacity){
if (initCapacity <= 0) {
throw new IllegalArgumentException("数组的初始化大小必须大于0");
}
elements = new Object[initCapacity];
maxSize = initCapacity;
rear = front = size = 0;
}
public LitGrassCircleQueue(){
this(DEFAULT_CAPACITY);
}
//入队
public void offer(T e){
if (size == maxSize - 1) {
ensureCapacity(maxSize * 2 + 1);
}
elements[rear] = e;
rear = (rear + 1) % maxSize;
size++;
}
//出队
public T poll(){
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
T e = (T) elements[front];
elements[front] = null;
front = (front + 1) % maxSize;
size--;
return e;
}
//获取头部元素
public T peek(){
if (isEmpty()) {
return null;
}
return (T) elements[front];
}
public boolean isEmpty(){
return size == 0;
}
//扩容
private void ensureCapacity(int newCapacity){
if(newCapacity < maxSize){
return;
}
Object[] old = elements;
Object[] newElements = new Object[newCapacity];
for (int i = 0; i < maxSize; i++) {
newElements[i] = old[front];
front = (front + 1) % maxSize;
}
elements = newElements;
front = 0;
rear = size;
maxSize = newCapacity;
}
public int size(){
return size;
}
public int maxSize(){
return maxSize;
}
public boolean isFull(){
return size == maxSize - 1;
}
}