顺序队列实行先进先出的原则,需要加上front和rear两个变量分别指示队首和队尾在数组中的位置,初值为0。
在非空队列中,front指向队首元素,rear指向队尾元素的下一个存储位置。
由于顺序队列中会产生假溢出的情形,例如一个有6个存储空间的队列存满,并且出队2次之后,
我们无法在第七个存储空间继续入队,但实际上此队列在前方仍然有两个空余的存储空间。
解决这个问题,最好的办法就是将顺序队列看成是一个逻辑上首位相连的循环队列,
转换可以用rear=(rear+1)%maxSize来实现。
在循环队列中会有一个问题:无法区分队空和队满的状态,因为队空和队满的条件都是rear==front。
解决方法有少用一个存储单元,设置一个标志变量,设置一个计数器3种方法,
这里我们使用少用一个存储单元,即队空的条件为rear==front, 队满的条件为front=(rear+1)%maxSize。
实现代码如下:
接口:
package queueTest;
public interface IQueue {
public void clear();
public boolean isEmpty();
public int length();
public Object peek();// 取队首元素
public void offer(Object x) throws Exception;// 入队
public Object poll();// 出队
public void display();
}
循环队列:
package queueTest;
public class CircleSqQueue implements IQueue {
private Object[] queueElem;//队列存储空间
private int front;//队首引用,若队列不为空,指向队首元素
private int rear;//队尾引用,若队列不为空,指向队尾的下一个元素
public CircleSqQueue(int maxsize) {
front=rear=0;
queueElem=new Object[maxsize];//分配maxsize个单元
}
@Override
public void clear() {
front=rear=0;
}
@Override
public boolean isEmpty() {
return rear==front;
}
@Override
public int length() {
return (rear-front+queueElem.length)%queueElem.length;
}
@Override
public Object peek() {
if(front==rear){
return null;
}
else{
return queueElem[front];
}
}
@Override
public void offer(Object x) throws Exception {
if((rear+1)%queueElem.length==front){//队满
throw new Exception("队列已满");
}
else{
queueElem[rear]=x;
rear=(rear+1)%queueElem.length;//修改队尾指针
}
}
@Override
public Object poll() {
if(front==rear){
return null;//队列为空
}
else{
Object t=queueElem[front];
front=(front+1)%queueElem.length;
return t;
}
}
@Override
public void display() {
if(!isEmpty()){
for(int i=front;i!=rear;i=(i+1)%queueElem.length){
System.out.println(queueElem[i].toString()+" ");
}
}
else{
System.out.println("此队列为空");
}
}
}