要通过数组来模拟一个队列,首先了解一下队列的基本概念
1.队列(Queue)队列是一种先进先出(FirstInFirstOut,FIFO)的线性表。它只允许在表的一端进行插入,而在另一端进行删除。向队列中插入元素源称为入队,从队列中删除元素称为出队。
2)队首(front):允许进行删除的一端称为队首。
2)队尾(rear):允许进行插入的一端称为队尾。
4)队列的长度:队列中数据元百素的个数表示队列的长度。
5)空队列:当队列中没有元素时称为空队列。
6)先进先出表(FIFO):队列的修改是按先进先出的原则进行的,又称为先进先出表(FIFO)。
首先 我们需要以下这4个成员变量,以及队列的初始化操作
private int maxSize;//最大容量
private int front;//队列头
private int rear;//队列尾
private int[] arr;//该数组用于存放数据
public ArrayQueue(int arrMaxSize) {
this.front = -1;//指向队列头部 (第一个数据的前一个位置)
this.rear = -1;//指向队列尾 (指向队列尾的具体位置,就是最后一个数据)
maxSize = arrMaxSize;
this.arr = new int[arrMaxSize];
}
接下来,我们需要判断队列满和队列空的方法,当rear=maxSize-1时,可以得知队列满,当rear = front时,可以得知队列是为空的。
public boolean isFull() {
return rear == maxSize - 1;
}
public boolean isEmpty() {
return rear == front;
}
然后我们来完成队列的入队和出队方法:入队列,我们将队尾rear++,并值赋给arr[rear]。出队列的话,我们将队头front++,并将出队的值arr[front]返回。
//添加数据到队列
public void addQueue(int data) {
if (isFull()) {
System.out.println("队列满,不能加入数据!");
return;
}
rear++;
arr[rear] = data;
}
//出队列
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空");
}
front++;
return arr[front];
}
完整实现代码如下:
class ArrayQueue {
private int maxSize;//最大容量
private int front;//队列头
private int rear;//队列尾
private int[] arr;//该数组用于存放数据
public ArrayQueue(int arrMaxSize) {
this.front = -1;//指向队列头部 (第一个数据的前一个位置)
this.rear = -1;//指向队列尾 (指向队列尾的具体位置,就是最后一个数据)
maxSize = arrMaxSize;
this.arr = new int[arrMaxSize];
}
public boolean isFull() {
return rear == maxSize - 1;
}
public boolean isEmpty() {
return rear == front;
}
//添加数据到队列
public void addQueue(int data) {
if (isFull()) {
System.out.println("队列满,不能加入数据!");
return;
}
rear++;
arr[rear] = data;
}
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空");
}
front++;
return arr[front];
}
public void showQueue() {
if (isEmpty()) {
System.out.println("队列空");
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.printf("arr[%d] = %d \n", i, arr[i]);
}
}
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空");
}
return arr[front + 1];
}
}
这样一个简单的队列就实现了,但是由于没有实现环形队列,导致即使我们在栈满后,即使出栈依然无法再次入栈。于是我们就想到了要实现环形队列。
class CircleArrayQueue {
private int front;
private int rear;
private int maxSize;
private int[] arr;
public CircleArrayQueue(int arrayMaxSize) {
this.maxSize = arrayMaxSize;
arr = new int[arrayMaxSize];
}
//判断栈满
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
//判断栈空
public boolean isEmpty() {
return rear == front;
}
//添加数据到队列
public void addQueue(int data) {
if (isFull()) {
System.out.println("队列满,不能加入数据!");
return;
}
arr[rear] = data;
//通过取模的模式,当rear = maxSize-1时
//再次添加又从0开始
rear = (rear + 1) % maxSize;
}
//出栈
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空");
}
int val = arr[front];
front = (front + 1) % maxSize;
return val;
}
public void showQueue() {
if (isEmpty()) {
System.out.println("队列空");
return;
}
for (int i = front; i < front + getMaxSize(); i++) {
System.out.printf("arr[%d] = %d \n", i % maxSize, arr[i % maxSize]);
}
}
//获取真实数据的个数
public int getMaxSize() {
return (rear + maxSize - front) % maxSize;
}
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("队列空");
}
return arr[front];
}
}
通过取模的方式,可以使得我们的队列循环使用,达成环的效果。