2. 队列
2.1 队列介绍
- 队列是一个有序列表,可以使用数组或者链表来实现
- 遵循先进先出的原则。即:先存入队列的数组,先取出;后存入队列的元素,后取出
- 队列的示意图
2.2 使用数组模拟队列
如上图所示, 使用数组的结构来模拟队列,需要声明一个最大的容量maxSize。同时,因为输出于输出分别在队列的前后端进行,因此我们需要证明两个指针front和rear,分别指向队列的头部和尾部。其中,front和队列的输出有关,rear和队列的输入有关。
队列中应当由两个方法,分别是添加元素add()和取出元素remove()。
2.3 数组队列的代码实现
class MyQueue {
// 指定queue的最大容量
private int maxLength;
int[] queue;
// 构造方法
public MyQueue(int maxLength) {
this.maxLength = maxLength;
this.queue = new int[maxLength];
}
// 无参构造器
public MyQueue() { }
// set方法
public void setMaxLength(int maxLength) {
this.maxLength = maxLength;
}
// 创建数组
// 注意:不能使用如上的方法来创建数组,类中属性的初始化工作只能在构造方法中来完成
// int[] queue = new int[maxLength];
// 初始化队列的两个指针
int front = -1;
int rear = -1;
// 队列的添加元素方法
// 添加元素首先应当注意的是队列是否为满,只有队列不是满的时候才能添加元素
public void add(int element) {
if (rear == (maxLength - 1)) {
throw new IndexOutOfBoundsException("队列是满队列,添加元素失败");
}
queue[++rear] = element;
}
// 删减元素
// 删减元素首先判断队列是否为空,只有队列非空的时候才能删减元素
public void remove() {
if (front == rear) {
throw new IndexOutOfBoundsException("队列为空队列,删减元素失败");
}
queue[++front] = 0;
}
}
当前队列存在的问题:数组使用一次就不能使用了,没有达到复用的效果。
2.4 数组环形队列
2.4.1 思路分析
-
令front指向队列的第一个元素,front的初始值未0
-
令rear指向队列的最后一个元素的后一个位置,rear的初始值为0
-
队列满的条件是:
(rear + 1) % maxLength == front
-
队列为空的条件是:
rear == front
根据以上分析,创建的数组大小为maxLength,但实际上队列中的元素只有maxLength-1个。牺牲的那一个位置是为了更简便判断出队列为空的条件。
-
队列中有效元素的个数是:
(rear + maxSize - front) % maxSize
2.4.2 代码实现
class CycleQueue {
// 类中的属性字段
private int front = 0;
private int rear = 0;
int[] queue;
private int maxLength;
// 无参构造方法
public CycleQueue() { }
// 有参构造方法
public CycleQueue(int maxLength) {
this.maxLength = maxLength;
this.queue = new int[maxLength];
}
// 添加元素的方法
public void add(int element) {
// 首先应当判断队列是否为满
if (isFull()) {
throw new RuntimeException("循环队列已满");
}
queue[(rear++) % maxLength] = element;
}
// 移除元素的方法
public void remove() {
if (isEmpty()) {
throw new RuntimeException("循环队列已空");
}
queue[(front++) % maxLength] = 0;
}
// 打印队列的方法
public void print() {
// 判断队列是否为空
if (isEmpty()) {
throw new RunimeException("队列为空,无法打印");
}
// 队列的有效长度为
int length = (rear - front + maxLength) % maxLength;
for (int i = front; i <= front + length; i++) {
System.out.printf("%d\t", queue[i]);
}
}
// 判断队列是否为空
public boolean isEmpty() {
return front == rear;
}
// 判断队列是否为满
public boolean isFull() {
return (rear + 1) % maxLength == front;
}
}
return front == rear;
}
// 判断队列是否为满
public boolean isFull() {
return (rear + 1) % maxLength == front;
}
}