1. 数组模拟队列
-
队列本身是有序列表,具有先入先出的特性,可以使用数组或链表来实现。 -
基础构成:
- maxSize:数组的最大容量,按照约定空出一个容量,最多能存如maxSize - 1个数据。
- front:队列头索引,初始为-1,指向队列头前一个数据。
- rear:队列尾,初始为-1,指向队列尾最后一个数据。
-
特殊场景:
- 队列已满: rear = maxSize - 1
- 队列已空: rear = front
-
基础操作:
- 加入数据:(rear < maxSize - 1) rear++; arr[rear] = n
- 取出数据:(rear > front) front++; return arr[front]
-
模拟实现 import com.sun.java.accessibility.util.EventID;
public class Queue {
private int maxSize;
private int front;
private int rear;
private int[] arr;
public Queue(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
rear = -1;
front = -1;
}
public void add(int num) {
if (isFull()) {
throw new RuntimeException("Queue is full");
}
arr[++rear] = num;
}
public int push() {
if (isEmpty()) {
throw new RuntimeException("Queue is empty");
}
return arr[++front];
}
public boolean isEmpty() {
return front == rear;
}
public boolean isFull() {
return rear == maxSize - 1;
}
}
-
问题点: 数组不可复用, 只能使用一次(解决方案: 通过%取模构建环形队列, 复用数组)
2. 环形队列
-
基本构造
- front:指向队列第一个元素,但是初始值为0
- rear:指向队列最后一个元素的后一个位置,初始值为0
- 队列已满:(rear + 1)% maxSize == front
- 队列为空:rear == front
- 队列的有效个数:(rear + maxSize - front)% maxSize
- 为了区分空和满的情况,环形队列默认空出一个位置
-
基础操作
-
加入数据:arr[rear] = n, rear = (rear + 1) % maxSize -
取出数据:
- 临时变量保存arr[front]
- front = (front + 1)% maxSize
- 返回临时变量
-
显示所有 (int i = front,i < 有效个数 + front, i++)
arr[i % maxSize]
-
代码实现
public class CircleQueue {
private int maxSize;
private int front;
private int rear;
private int[] arr;
public CircleQueue(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
}
public void add(int num) {
if (isFull()) {
throw new RuntimeException("Queue is full!");
}
arr[rear] = num;
rear = (rear + 1) % maxSize;
}
public int push() {
if (isEmpty()) {
throw new RuntimeException("Queue is empty!");
}
int num = arr[front];
front = (front + 1) % maxSize;
return num;
}
public void show() {
if (isEmpty()) {
return;
}
for (int i = front; i < front + size(); i++) {
System.out.println(arr[i % maxSize]);
}
}
public int size() {
return (rear + maxSize - front) % maxSize;
}
private boolean isEmpty() {
return front == rear;
}
private boolean isFull() {
return (rear + 1) % maxSize == front;
}
}
|