环形队列
队列,是一个序列表,遵循先进先出原则,这边文章使用数组实现。
既然是先进的先出去后进的后出去,这个实现应该大致包括以下方法:
//初始化创建队列
isEmpty()//判断是否为空
isFull()//队列是否已满
addData();//向队列添加元素
takeData();//从队列取元素
showQueue();//显示队列(按顺序)
下面来分析下队列存取过程,先画个示意图:
此队列看似是可行的而且判断也简单,但是实现后会发现当四个数字存满后都取出时front指向顶端,此时无法再向里面插入数据,此时rear为5,实际应当指向队低0的位置,所以在此情况下可把再次指向0这种情况想象成环形,
实现上述环状结构有两种方式实现,两种方案对应上述应实现的方法实现逻辑不同,这两种方案是:
1 按上图那样去分析做对应逻辑编写,但在队列为满和队列为空两个条件有相同的值即front = rear 时无法判断为满为空,此时需要一个标识记录下目前一共有多少个元素,可以在addData方法中标识加1,takeData方法中标识减一按时记录队列元素个数。
2 将数组中一个元素留下不保存元素,当front与rear相等时代表队列为空,当(rear+1)%数组长度 = front 为什么要除以数组长度求余?请看下面的图:
现贴出上述代码实现:
public class ArrayQueueDemo {
public static void main(String[] args) {
ArrayQueue aq = new ArrayQueue(5);
aq.addData(1);
aq.addData(2);
aq.addData(3);
aq.addData(4);
aq.takeData();
aq.showQueue();
}
}
class ArrayQueue {
private int[] arrayQ;
private int maxSize;
private int front =0;
private int rear =0;
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;// 因为少一个可存储位置用于判断,所以创建时多加一个位置
maxSize++;
arrayQ = new int[maxSize];
}
public boolean isEmpty() {
if (front == rear) {
return true;
}
return false;
}
public boolean isFull() {
if (((rear + 1) % maxSize) == front) {
return true;
}
return false;
}
public void addData(int value) {
if (isFull()) {
System.out.println("队列已满不能再存数据");
} else {
arrayQ[rear] = value;
rear = (rear + 1) % maxSize;
}
}
public int takeData() {
if (isEmpty()) {
System.out.println("队列为空没有数据");
throw new RuntimeException();
} else {
int a = arrayQ[front];
front = (front + 1) % maxSize;
return a;
}
}
public int size() {
return (rear + maxSize - front) % maxSize;
}
public void showQueue() {
if (isEmpty()) {
System.out.println();
}
for (int i = front; i < front + size(); i++) {
System.out.println(arrayQ[i % maxSize] + "\t");
}
}
}