队列
概念
public interface MQueue{
//判断是否空队列
boolean isEmpty();
//判断是否满队列
boolean isFull();
//取队首
T getHead();
//进队
void add(T x);
//出队
T remove();
}
队列可以用两种方式存储,顺序存储和链式存储,顺序队列中一种特殊的存储方式是循环队列。
链式队列
习惯上将表头作为队首,表尾作为队尾,插入和删除的复杂度都是 O(1)。
继承方式实现链式队列
/**
* Created by nvgtor on 2016/4/27.
* 其中 add、remove、isEmpty方法在 MLinkList 中已经实现
*/
public class MLinkQue extends MLinkList {
public MLinkQue(){
super();
}
public boolean isFull(){
return false;
}
public T getHead(){
return get(0);
}
}
聚合方式实现链式队列
public class MLinkQue2 {
private MLinkList linkList;
public MLinkQue2(){
linkList = new MLinkList();
}
public T getHead(){
return linkList.get(0);
}
public void add(T x){
linkList.add(x);
}
public T remove(){
return linkList.remove(0);
}
public boolean isEmpty(){
return linkList.isEmpty();
}
public boolean isFull(){
return false;
}
}
顺序队列
顺序队列用一个顺序表(数组)作为队列的存储空间。存在假溢出问题。假设数组 seqQue[maxSize] 作为队列的存储空间,rear 指向队尾元素的下一个位置,初始 front = rear = 0;
- 空队列: front == rear;
- 入队: seqQue[rear] = x; rear++;
- 出队: x = seqQue[front]; front++;
- 队满条件: rear == maxSize;
循环队列
把数组的头指针和尾指针链接起来,形成一个圆环,即为循环队列。可以解决假溢出问题,但是浪费一个存储单元。用数组data[maxSize]存储。
- 队空: front == rear;
- 队满: (rear + 1) % maxSize == front;
- 进队: data[rear] = x; rear = (rear + 1) % maxSize;
- 出队: x = data[front]; front = (front + 1) % maxSize;
实现:
public class MSeqQue implements MQueue {
private int front, rear, maxSize;
Object[] data;
public MSeqQue(int maxQueueSize){
maxSize = maxQueueSize + 1;
front = rear = 0;
data = new Object[maxSize];
}
@Override
public boolean isEmpty() {
return front == rear;
}
@Override
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
@Override
public T getHead() {
return (T) data[front];
}
@Override
public void add(T x) {
data[rear] = x;
rear = (rear + 1) % maxSize;
}
@Override
public T remove() {
T x = (T) data[front];
front = (front + 1) % maxSize;
return x;
}
}