队列是另一种特殊的线性表,只允许在表尾插入数据,在表头删除数据
具有先进先出的特性,也可用两种存储结构实现
队列的操作有
public interface IQueue
{
public void clear(); //置空
public boolean isEmpty(); //判空
public int length(); //求长度
public Object peek(); //取队首元素
public void offer(Object x);//入队
public Object poll(); //出队
}
循环顺序队列的实现如下
public class CircleSqQueue implements IQueue
{
private Object[] queueElem; //存储队列元素
private int front; //队首引用
private int rear; //rear指向队尾元素的下一个存储位置
public CircleSqQueue(int maxSize)
{
queueElem = new Object[maxSize]; //分配存储单元
front = rear = 0; //初始化为0
}
@Override
public void clear() {
rear = front;
}
@Override
public boolean isEmpty() {
return rear == front; //不难发现,当队满时,rear==front也成立
} //采取少用一个存储单元的方法,使得队满的判断为
//front == (rear+1)%queueElem.length
@Override
public int length() {
return (rear-front+queueElem.length)%queueElem.length; //考虑(rear-front)为负的情况
}
@Override
public Object peek() {
if(front==rear) //要先判断队列是否为空
return null;
else
return queueElem[front];
}
@Override
public void offer(Object x) {
if((rear+1)%queueElem.length == front) //队列已满
{
System.out.println("队列已满");
return;
}
queueElem[rear] = x;
rear = (rear+1)%queueElem.length; //修改队尾指针
}
@Override
public Object poll() {
if(rear == front) //要先判断是否为空
return null;
Object peek = queueElem[front];
front = (front+1)%queueElem.length;
return peek;
}
}
队列的链式存储用不带头结点的单链表实现
public class LinkQueue implements IQueue
{
private Node front;
private Node rear;
public LinkQueue()
{
front = rear = null;
}
@Override
public void clear() {
front = rear = null;
}
@Override
public boolean isEmpty() {
return front == null; //不带头节点,不能用front == rear
}
@Override
public int length() {
int length = 0;
Node p = front;
while(p!=null)
{
p = p.next; //不能用front = front.next这样会改变队列结构
length++;
}
return length;
}
@Override
public Object peek() {
if(front != null) //首先要判断队列是否为空
return front.data;
else
return null;
}
@Override
public void offer(Object x) {
Node p = new Node(x);
if(front != null)
{
rear.next = p;
rear = p; //队尾更新了
}else
{
front = rear = p; //队列为空时,入队后,只有一个元素,队首队尾都要指向它
}
}
@Override
public Object poll() {
if(front==null)
return null;
else {
Node p = front;
front = front.next;
if(p == rear) //要单独判断删除的节点是不是队尾节点(即最后一个节点)
rear = null;
return p.data;
}
}
}