public class Queue {
private int MAX_CAPACITY;
private int[] data;
private int front;
private int rear;
private int nItems;
public Queue(int capacity){
if(capacity < 0)
throw new IllegalArgumentException("Illegal capacity: " + capacity);
MAX_CAPACITY = capacity;
data = new int[MAX_CAPACITY];
front = 0;
rear = -1;
nItems = 0;
}
public Queue(){
this(10);
}
public void insert(int value){
if(isFull())
throw new FullQueueException("queue is full");
if(rear == MAX_CAPACITY-1) // 因为是数组实现,所以数组顶端应该是MAX_CAPACITY-1
rear = -1; // 为什么初始状态是-1,因为数组下标从0开始
data[++rear] = value;
nItems++;
}
public int remove(){
if(isEmpty())
throw new EmptyQueueException("queue is empty");
int temp = data[front++];
if(front == MAX_CAPACITY)
front = 0; // 数组下标从0开始,front=0可以直接取
nItems--; // 多维护一个队列大小变量,可以让isFull()、isEmpty()函数变得很简洁
return temp;
}
public int peek(){
if(isEmpty())
throw new EmptyQueueException("queue is empty");
return data[front];
}
public boolean isFull(){
return (nItems == MAX_CAPACITY);
}
public boolean isEmpty(){
return (nItems == 0);
}
public int size(){
return nItems;
}
public static void main(String[] args) {
Random random = new Random();
Queue queue = new Queue();
int CAPACITY = 10;
System.out.println("----入列-----");
for(int i=0;i<CAPACITY;i++){
queue.insert(random.nextInt(100));
}
System.out.println("元素数量:" + queue.size());
System.out.println("----出列-----");
for(int i=0;i<CAPACITY;i++){
System.out.println(queue.remove());
}
}
}
注意几点:
1、解决”假溢出”问题:循环队列
2、担心rear一直循环会覆盖原来的值?:在insert之前加入isFull()判断,如果队列满(front==rear),则不会继续插入
3、担心front一直循环会取不到值?:在remove之前加入isEmpty()判断,如果队列为空(front==rear),则不会继续取值
4、front和rear一直互相追着跑
5、ADT中多维护一个变量(标识当前队列中元素数量),会让isFull()、isEmpty()代码简洁很多
6、异常处理原理同堆栈