1.问题
对于普通队列而言,数组不能重复使用,这样就造成了空间浪费。怎样才能使队列能够重复利用呢?将队列改成一个环形的,这样就可以重复利用了。
2.分析实现
分析
- front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素
front 的初始值 = 0 - rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
rear 的初始值 = 0 - 当队列满时,条件是 (rear + 1) % maxSize == front 【满】
- 对队列为空的条件, rear == front 空
- 当我们这样分析, 队列中有效的数据的个数 (rear + maxSize - front) % maxSize
- 我们就可以在原来的队列上修改得到,一个环形队列
实现
public class CircleQueue {
private int maxSize; //数组的最大容量
private int rear; //队列尾 rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
private int front; //队列头
private int[] arr; //用于存放数据,模拟队列
//初始化队列
public CircleQueue(int maxSize){
this.maxSize = maxSize;
arr = new int[maxSize];
}
//判断队列是否满
public boolean isFull(){
System.out.println("rear="+rear+"\tfront="+front);
return (rear+1)%maxSize==front;
}
//判断队列是否为空
public boolean isEmpty(){
return rear == front;
}
//往队列添加数据
public void addQueue(int n){
//判断是否满
if (isFull()){
System.out.println("队列满,不能添加数据");
return;
}
arr[rear] = n;
rear = (rear+1)%maxSize;
}
//从队列去取数据
public int getQueue(){
//判断是否为空
if(isEmpty()){
throw new RuntimeException("队列为空,没有数据可取");
}
int value = arr[front];
front = (front+1)%maxSize;
System.out.println("rear="+rear+"\tfront="+front);
return value;
}
//显示队列所有数据
public void showQueue(){
//判断是否为空
if(isEmpty()){
System.out.println("队列为空,没有数据可显示");
return;
}
for (int i = front; i < front + size(); i++) {
System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]);
}
}
//显示队头数据
public int showQueueHead(){
//判断是否为空
if(isEmpty()){
throw new RuntimeException("队列为空,没有数据可显示");
}
return arr[front];
}
//求当前队列有效数个数
public int size(){
return (rear-front+maxSize)%maxSize;
}
}