使用数组实现循环队列,这里实现了add和poll两个关键接口
普通数组实现队列时,数组末端元素占满后需要检查首端是否占满,若未占满进行整体向前复制,若都占满则进行扩容;
循环队列优势在于仅在扩容时才进行数组复制操作,其余仅仅是根据tail索引添加元素,但会使用一个多余空间记录下一次添加时的索引,这样很好理解当first=tail时队列为空。
public class MyCircleQueue<T> implements MyQueue<T> {
private Object[] elements;
private static final int MIN_INITIAL_CAPACITY = 8;
private int first;
private int tail;
public MyCircleQueue() {
this(MIN_INITIAL_CAPACITY + 1);
}
public MyCircleQueue(int size) {
if (size <= 0)
throw new IllegalArgumentException("size is not less than 0");
elements = new Object[size];
}
@Override
public boolean add(T t) {
elements[tail] = t;
if (tail + 1 == elements.length) {
if (first == 0) {
Object[] newArr = new Object[elements.length<<1];
System.arraycopy(elements,0,newArr,0, elements.length);
elements = newArr;
tail++;
} else {
tail = 0;
}
}else if (tail + 1 == first) {
Object[] newArr = new Object[elements.length<<1];
System.arraycopy(elements, first, newArr,0, elements.length - first);
System.arraycopy(elements,0,newArr,elements.length - first, first);
first = 0;
tail = elements.length;
elements = newArr;
} else {
tail++;
}
return true;
}
@Override
public T poll() {
if (first == tail)
return null;
T e = (T) elements[first];
elements[first] = null;
if (first == elements.length - 1)
first = 0;
else
first++;
return e;
}
@Override
public String toString() {
if (first == tail)
return "[]";
StringBuilder builder = new StringBuilder();
builder.append("[");
if (first < tail) {
for (int i = first; i < tail; i++)
builder.append(elements[i].toString() + ",");
} else {
for (int i = first; i < elements.length; i++)
builder.append(elements[i].toString() + ",");
for (int i = 0; i < tail; i++)
builder.append(elements[i].toString() + ",");
}
String str = builder.toString();
return str.substring(0,str.length() - 1) + "]";
}
}
使用求模实现循环队列
public class CircleQueue<T> implements MyQueue<T> {
private Object[] elements;
private static final int MIN_INITIAL_CAPACITY = 8;
private int first;
private int tail;
public CircleQueue() {
this(MIN_INITIAL_CAPACITY + 1);
}
public CircleQueue(int size) {
if (size <= 0)
throw new IllegalArgumentException("size is not less than 0");
elements = new Object[size];
}
@Override
public boolean add(T t) {
elements[tail] = t;
grow();
tail = (tail+1)%elements.length;
return true;
}
private void grow() {
if ((tail+1)%elements.length == first) {
Object[] newArr = new Object[elements.length<<1];
for (int i = 0; i < elements.length; i++)
newArr[i] = elements[(i + first)%elements.length];
tail = elements.length - 1;
elements = newArr;
first = 0;
}
}
@Override
public T poll() {
if (first == tail)
return null;
T e = (T) elements[first];
elements[first] = null;
first = (first + 1)%elements.length;
return e;
}
@Override
public String toString() {
if (first == tail)
return "[]";
StringBuilder builder = new StringBuilder();
builder.append("[");
for (int i = first; i != tail; i = (i + 1)%elements.length) {
builder.append(elements[i].toString() + ",");
}
String str = builder.toString();
return str.substring(0,str.length() - 1) + "]";
}
}