队列正如日常生活中的排队取餐一样,?先排队的先取餐出队,?后排队的后取餐出队.?先进先出(FIFO:first?in first out).
放在数组里面则是,?从数组的一段进一端出.?将数组中索引为0的位置设置为队头
public interface QueueInterface<V> {
// 入队
void offer(V v);
// 出队
V poll();
// 队列是否为空
boolean isEmpty();
// 查看队元头素
V peek();
// 获取队列中元素个数
int getSize();
}
public class MyLoopQueue<V> implements QueueInterface<V> {
private V[] data;// 循环队列的容器
private int capacity;// 容量的大小
private int front;// 队头索引
private int tail;// 队尾索引
private static int INITIALIZE_CAPACITY = 10;// 默认初始容量大小
// 在创建对象时, 创建的空间比用的的空间大1, 因为要区分判满和判空, 所以实际空间大小一定大于所用空间大小1
public MyLoopQueue() {
this.capacity = INITIALIZE_CAPACITY;// 默认初始化大小为10
this.data = (V[]) (new Object[this.capacity + 1]);
this.front = 0;
this.tail = 0;
}
public MyLoopQueue(int capacity) {
if (capacity <= 0) {
capacity = 10;
} else {
this.capacity = capacity;
INITIALIZE_CAPACITY = capacity;
}
this.data = (V[]) (new Object[this.capacity + 1]);
this.front = 0;
this.tail = 0;
}
@Override
public void offer(Object v) {
if (isFull()) {
resize(capacity * 2);
}
data[tail++] = (V) v;
tail = tail % (capacity + 1);
}
private boolean isFull() {
return front == (tail + 1) % (capacity + 1);
}
// 改变数组容量
private void resize(int newCapacity) {
V[] newData = (V[]) (new Object[newCapacity + 1]);
for (int i = 0; i < getSize(); i++) {
newData[i] = data[(front + i) % (capacity + 1)];
}
capacity = newCapacity;
data = newData;
front = 0;
tail = getSize();
}
@Override
public V poll() {
if (isEmpty()) {
return null;
}
V v = data[front++];
front = front % (capacity + 1);
if (getSize() <= (capacity) / 4 && capacity > INITIALIZE_CAPACITY) {
resize(capacity / 2);
}
return v;
}
@Override
public boolean isEmpty() {
return front == tail;
}
@Override
public V peek() {
if (isEmpty()) {
return null;
}
return data[front];
}
@Override
public int getSize() {
if (tail > front) {
return tail - front;
} else {
return (tail + capacity + 1) - front;
}
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
if (getSize()== 0) {
return "[]";
}
stringBuilder.append("[");
int i = 0;
for (; i < getSize() - 1; i++) {
if (i == 0) {
stringBuilder.append(data[front]);
} else {
stringBuilder.append(data[(front + i) % (capacity + 1)]);
}
stringBuilder.append(", ");
}
stringBuilder.append(data[(front + i) % (capacity + 1)]);
stringBuilder.append("]");
return stringBuilder.toString();
}
}