目录
说明:这里对上面的非环形队列进行优化,可以理解为将数组做成一个环形的(通过取模来实现)
队列的介绍
队列的概念
队列是一个有序列表,可以用数组或是链表来实现
队列的特点
先进先出,即先存进的数据要先取出,后存进后取出
图解如下
队列的实现
数组模拟队列(非环形队列)
思路
*队列本身是有序列表,用数组结构来存储队列,图解如下
*队列两个关键因素:队列头部和队列尾部,这里我们用front来记录队列头部的下标,用rear来记录队列的尾部下标,每次添加数据,rear改变,每次取出数据,front改变
*队列实现的几个关键方法1.判断队列(空或者满,方便后续调用)2.增删查,所谓增就是添加一个数据到队列,删就是从队列中取出一个数据,查就是展示队列所有元素和展示队列的头部元素
非环形队列具体代码实现
说明:这里我们指定rear 和front的初始值为-1来实现
private int maxSize; // 表示数组的最大容量
private int front; // 队列头的前一个位置
private int rear; // 队列尾
private int[] arr; // 该数据用于存放数据, 模拟队列
//创建一个队列的构造器
public ArrayQueue(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
front = -1;//指向队列头部的前一个位置
rear = -1;//指向队列尾部
}
//判断队列是否为空
public boolean isNull(){
return front == rear;
}
//判断队列是否为满
public boolean isFull(){
return rear == maxSize - 1;
}
//加一个数据到队列
public void add(int num){
//先判断是否为满
if(isFull()){
System.out.println("队列已满");
return;
}
rear++;//尾部后移
arr[rear] = num;
}
//出队列,并返回删除的元素
public int out(){
//先判断是否空
if(isNull()){
throw new RuntimeException("队列为空");
}
front++;
return arr[front];
}
//显示队列的所有数据
public void showQueue(){
//先判断是否为空
if(isNull()){
System.out.println("队列为空");
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.println("arr[" + i + "]" + "=" + arr[i]);
}
}
//显示队列的头数据
public int showHead(){
//先判断是否为空
if(isNull()){
throw new RuntimeException("队列为空");
}
return arr[front + 1];
}
问题分析
这里我们并未设置为环形队列,导致这是一个一次性队列,并不能重复增加,当数组第一次满了之后,就会导致数据加不进去,所以我们引出了环形队列来解决这个问题
环形队列
说明:这里对上面的非环形队列进行优化,可以理解为将数组做成一个环形的(通过取模来实现)
1.我们将队列的容量空出来一个作为约定,即队列的有效数据为数组的容量 - 1,这时判断队列满的条件应该为(rear + 1) % maxSize == front 【核心】
思路分析示意图
代码实现
private int maxSize; // 表示数组的最大容量
private int front; // 队列头,初始值为0
private int rear; // 队列尾的后一个位置,初始值为0
private int[] arr; // 该数据用于存放数据, 模拟队列
//创建一个队列的构造器
public CircleArray(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
}
//判断队列是否为空
public boolean isNull(){
return front == rear;
}
//判断队列是否为满
public boolean isFull(){
return (rear + 1) % maxSize == front;
}
//加一个数据到队列
public void add(int num){
//先判断是否为满
if(isFull()){
System.out.println("队列已满");
return;
}
arr[rear] = num;
rear = (rear + 1) % maxSize;//环形队列需要取模
}
//出队列,并返回删除的元素
public int out(){
//先判断是否空
if(isNull()){
throw new RuntimeException("队列为空");
}
int temp = arr[front];//用临时变量保存便于返回数据
front = (front + 1) % maxSize;
return temp;
}
//返回队列的有效数据
public int size(){
return (rear + maxSize - front) % maxSize;
}
//显示队列的所有数据
public void showQueue(){
//先判断是否为空
if(isNull()){
System.out.println("队列为空");
return;
}
for (int i = front; i < front + size(); i++) {
System.out.println("arr[" + i % maxSize + "]" + "=" + arr[i % maxSize]);
}
}
//显示队列的头数据
public int showHead(){
//先判断是否为空
if(isNull()){
throw new RuntimeException("队列为空");
}
return arr[front];
}