1.队列介绍
队列是一个有序列表
,可以用数组或是链表来实现,它遵循先进先出
原则
2.数组模拟实现队列
2.1.思路
队列本身是有序列表,若使用数组的结构来存储队列的数据:
- 设置
maxSize
为该队列最大容量 - 因为队列的输入输出分别从前后端来处理,因此需要
head
和tail
分别记录队列前后端的下标,head会随着数据的输出而改变,而tail随着数据的输入而改变 - 当tail==maxSize-1时队列已满
2.2.代码实现
//数组实现队列
class ArrayQueue{
//数组最大元素个数
private int maxSize;
//队列头
private int head;
//队列尾
private int tail;
//用于存放数据
private int[] arr;
//创建队列的构造器
public ArrayQueue(int arrMaxSize){
maxSize = arrMaxSize;
arr = new int[maxSize];
//指向队列头部的前一个位置
head = -1;
//指向队列最后一个数据即队尾
tail = -1;
}
//判断队列是否满
//满返回true,没满返回false
public boolean isFull(){
return tail == maxSize - 1;
}
//判断队列是否为空他,头尾相等为空
//空返回true,非空返回false
public boolean isEmpty(){
return tail == head;
}
//添加数据到队列
public void addQueue(int data){
//判满
if(isFull()){
System.out.println("队列已满");
return;
}
//tail后移
tail ++;
arr[tail] = data;
}
//出队获取数据
public int getData(){
//判空
if(isEmpty()){
//通过抛出异常来处理,throw本身会导致代码return
throw new RuntimeException("队列为空");
}
head ++;
return arr[head];
}
//显示队列所有数据
public void showQueue(){
//遍历
if(isEmpty()){
System.out.println("队列为空");
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.printf("%d ",arr[i]);
}
}
//显示队列的头
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
return arr[head + 1];
}
}
2.3.问题分析与解决
- 问题:目前实现的方法数组使用一次不能复用
- 解决:将数组使用算法改进成环形数组(取模方式)
3.环形数组实现队列(数组实现队列的优化)
3.1.思路
- head变量的含义作调整:head指向队列的第一个元素,也就是说arr[head]是队列的第一个元素,head初始值为0
- tail变量的含义作调整:tail指向队列的最后一个元素的后一个位置(希望空出一个空间作为约定),tail初始值为0
- 当队列满时,(tail+ 1) % maxSize = head
- 当队列为空时,tail == head
- 队列中有效的数据个数:(tail + maxSize - front) % maxSize
3.2.代码实现
class CircleArray{
//数组最大元素个数
private int maxSize;
//队列头
private int head;
//队列尾
private int tail;
//用于存放数据
private int[] arr;
public CircleArray(int arrayMaxSize){
maxSize = arrayMaxSize;
arr = new int[maxSize];
//指向队列头部的前一个位置
head = 0;
//指向队列最后一个数据即队尾
tail = 0;
}
//判断队列是否满
//满返回true,没满返回false
public boolean isFull(){
return (tail + 1) % maxSize == head;
}
//判断队列是否为空他,头尾相等为空
//空返回true,非空返回false
public boolean isEmpty(){
return tail == head;
}
//添加数据到队列
public void addQueue(int data){
//判满
if(isFull()){
System.out.println("队列已满");
return;
}
//直接将数据加入
arr[tail] = data;
//将tail后移
tail = (tail + 1) % maxSize;
}
//出队获取数据
public int getData(){
//判空
if(isEmpty()){
//通过抛出异常来处理,throw本身会导致代码return
throw new RuntimeException("队列为空");
}
//这里要分析出head是指向队列的第一个元素
//先把head对应的值保留到一个临时变量
//head后移
//返回临时变量
int value = arr[head];
head = (head + 1) % maxSize;
return value;
}
//求出当前队列有效数据个数
public int size(){
return (tail + maxSize - head) % maxSize;
}
//显示队列所有数据
public void showQueue(){
//遍历
if(isEmpty()){
System.out.println("队列为空");
return;
}
//从head开始遍历
for (int i = head; i < head + size(); i++) {
System.out.printf("%d ",arr[i % maxSize]);
}
}
//显示队列的头
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
return arr[head];
}
}