今天看了一个关于用数组实现循环队列的视频,视频中的数组总有一个元素是不被使用的,试着优化了一下。
视频中认为front与rear相等时就为空,我对此做了改进。
假设队列最大容量3个元素,当入队一个元素后,front=0,rear=1,入队第三个元素后,front=0,rear=0
front和rear都在做顺时针运动,如果front追上了rear发生重合,那就为空,如果是rear追上front队列就满了。
package rx;
/**
* @ClassName: ArrayQueueDemo
* @Description: 循环队列测试
* @author: rx
* @date: 2021年9月21日 下午5:29:39
*/
public class ArrayQueueDemo {
public static void main(String[] args) {
ArrayQueue q = new ArrayQueue(3);
q.add(1);
q.add(2);
q.add(3);
q.out();
q.add(4);
q.out();
q.out();
q.add(5);
q.add(6);
q.show();
System.err.println(q.size());
}
}
/**
*
* @ClassName: ArrayQueue
* @Description: 循环队列 数组使用率100%
* @author: rx
* @date: 2021年9月21日 下午5:39:03
*/
class ArrayQueue{
private int front; //队首的索引
private int rear; //将要入队的元素索引
private int maxSize; //队列的最大长度
private boolean isEmpty; //队列是否为空
private int[] attr;
public ArrayQueue(int maxSize) {
this.front = 0;
this.rear = 0;
this.isEmpty = true; //初始队列为空
this.attr = new int[maxSize];
this.maxSize = maxSize;
}
/**
*
* @Title: add
* @Description: 入队方法
* @param: @param n
* @return: void
* @throws
*/
public void add(int n) {
// 队列满了不可以入队
if(isFull()) {
throw new RuntimeException("队列满了,不可入队");
}
// 队列不再为空
this.isEmpty = false;
attr[rear] = n;
// rear = (rear+1)%(maxSize+1) == maxSize ? 0 : (rear+1)%(maxSize+1); 之前的想法多余了
rear = (rear+1)%maxSize;
}
/**
*
* @Title: out
* @Description: 出列方法
* @param: @return
* @return: int
* @throws
*/
public int out() {
if(this.isEmpty) {
throw new RuntimeException("队列为空,不可出列");
}
int value = attr[this.front];
this.front = (front+1)%maxSize;
if(this.front==this.rear) {
this.isEmpty=true;
}
return value;
}
/**
*
* @Title: isFull
* @Description: 判断队列是否满了
* @param: @return
* @return: boolean
* @throws
*/
public boolean isFull() {
//如果队列状态非空并且front等于rear则满了
if(this.isEmpty == false && this.front == this.rear) {
return true;
}else {
return false;
}
}
public void show() {
if(this.isEmpty) {
throw new RuntimeException("队列为空");
}
//从队首遍历到队尾
for(int i = front;i<front+this.size();i++) {
System.out.println(attr[i%maxSize]);
}
}
/**
*
* @Title: size
* @Description: 获取队列的有效长度
* @param: @return
* @return: int
* @throws
*/
public int size() {
//如果队首队尾重合且队列状态非空则为满了
if(this.front == this.rear) {
if(this.isEmpty == false) {
return maxSize;
}else {
return 0;
}
}else {
return Math.abs(front-rear);
}
}
}