//循环队列的出队复杂度是O(1),不需要移动,只需要变更front++
//数组队列的出队是O(n),每出队一次,所有的元素都要向前移一个位置
public class LoopQueue<E> {
private E[] data;
private int front,tail;
private int size; //队列的大小,可以通过front和tail计算出
public LoopQueue() {
data=(E[])new Object[11]; //初始11个长度的数组是因为循环队列需要浪费一个数组的空间,实际可存10个
front=0;
tail=0;
size=0;
}
public LoopQueue(int capacity) {
data=(E[])new Object[capacity+1]; //初始化capacity+1个长度的数组是因为循环队列需要浪费一个数组的空间
front=0;
tail=0;
size=0;
}
/**
* 得到队列的容量
* @return 队列的容量
*/
public int getCapacity() {
return data.length-1;
}
/**
* 判断是否为空
* @return 是否
*/
public boolean isEmpty() {
return front==tail;
}
/**
* 返回现在的队列存了多少元素
* @return 元素个数
*/
public int getSize() {
return size;
}
/**
* 判断队列是否满了
* @return
*/
public boolean isFull() {
return (tail+1)%data.length==front; //队尾+1是否为队头
}
/**
* 入队,从队尾插入一个元素
*/
public void enqueue(E e) {
if (isFull()) {
resize(getCapacity()*2);
}
data[tail]=e;
tail=(tail+1)%data.length;
size++;
}
/**
* 出队
* @return
*/
public E dequeue() {
if (isEmpty()) {
throw new IllegalArgumentException("当前队列为空,不允许出队");
}else {
E res=data[front];
data[front]=null; //释放
front=(front+1)%data.length;
size--;
if (size==getCapacity()/4&&getCapacity()/2!=0) {
resize(getCapacity()/2);
}
return res;
}
}
/**
* 查看队头元素
* @return 队头元素
*/
public E getFront() {
if (isEmpty()) {
throw new IllegalArgumentException("当前队列为空,不允许出队");
}else {
return data[front];
}
}
/**
* 改变数组的大小
* @param newCapacity
*/
private void resize(int newCapacity) {
E[] newdata=(E[]) new Object[newCapacity+1]; //新建一个数组
for (int i = 0; i < size; i++) { //遍历旧数组的值
newdata[i]=data[(i+front)%data.length]; //将旧数组的值赋给新数组
}
data=newdata; //完成数组容量的变换
front=0;
tail=size;
}
}
java语言实现循环队列(附详细注释)
最新推荐文章于 2024-08-09 23:52:18 发布