Java数组实现队列
队列的应用场景
银行排队叫号系统
队列介绍
队列是一个有序列表,可以用数组和链表来实现
队列有一个原则。即:先存入队列的数据要先取出。后存入的要后取出
数组模拟队列的思路分析
因为队列的输出、输入分别从前后端来处理,因此需要两个变量front及rear分别记录队列前后端的下标,front会随着输出而改变,而rear则是随着数据输入而改变。而MaxSize则是数组队列的大小。
创建一个数组队列的类,其中需要包含以下几个方法:
boolean isFull():判断队列是否已满
boolean isEmpty():判断队列是否为空
void add(int date):添加数据
int get():取出数据
void show():遍历队列
数组模拟队列代码实现
这里使用Java实现,首先定义一个数组队列的类,其中含有四个属性:
int front:指向队列第一个数据的前一个位置
int rear:指向队列最后一个数据的位置
int MAXSIZE:表示队列的大小
int arr[]:用于存储队列数据
代码如下:
class ArrayQueue{
private int front = -1;//指向队列第一个数据的前一个位置
private int rear = 0;//指向队列最后一个数据的位置
private final int MAXSIZE;//表示队列的大小
private int[] arr;//用于存储队列数据
public ArrayQueue(int size){
MAXSIZE = size;
arr = new int[MAXSIZE];
}
}
判断队列是否已满的条件是:rear == MAXSIZE,isFull方法实现如下:
public boolean isFull(){
return rear == MAXSIZE;
}
判断队列是否为空的条件是:rear - front == 1,isEmpty方法实现如下:
public boolean isEmpty(){
return rear - front == 1;
}
添加数据时,我们先要判断队列是否已满,若队列仍有空位,则可以添加。将数据添加至rear所指向的位置后,rear后移。代码实现如下:
public void add(int data){
if (isFull()){
throw new RuntimeException("队列已满");
}
arr[rear] = data;
rear ++;
}
获取数据时,我们先要判断队列是否为空,若队列为非空,则能够获取数据。我们先将front后移以为后获取数据。代码实现如下:
public int get(){
if (isEmpty()){
throw new RuntimeException("队列为空,无法获取数据");
}
front ++;
return arr[front];
}
遍历队列:
public void show(){
for (int i : arr){
System.out.println(i);
}
}
至此,一个用数组实现的队列就完成了。
但上述实现方法有一定的缺陷,即无法复用。为了实现复用性,让我们换一种实现方式:环形队列。
数组模拟环形队列思路分析
思路与队列大致相同,但要完成环形队列的模拟必须要使用取余的方法对首尾指针位置进行计算。我们设值两个指针,front取余后表示队列第一个值所在位置,rear取余后表示队列最后一个值所在位置。MAXSIZE仍然表示队列大小。仍包含以下几个方法:
boolean isFull():判断队列是否已满
boolean isEmpty():判断队列是否为空
void add(int date):添加数据
int get():取出数据
void show():遍历队列
数组模拟环形队列代码实现
环形队列包含以下四个属性:
int front:指向队列第一个数据的位置
int rear:指向队列最后一个数据的位置
int MAXSIZE:表示队列的大小
int arr[]:用于存储队列数据
代码实现如下:
class ArrayCircleQueue{
private int front = 0;//取余后指向队列第一个数据的后一个位置
private int rear = 0;//取余后指向队列最后一个数据的后一个位置
private final int MAXSIZE;//表示队列的大小
private int[] arr;//用于存储队列数据
public ArrayCircleQueue(int size){
MAXSIZE = size;
arr = new int[MAXSIZE];
}
}
判断队列是否已满的条件是:rear % MAXSIZE == front && rear != front,isFull方法实现如下:
public boolean isFull(){
return rear % MAXSIZE == front && rear != front;
}
判断队列是否为空的条件是:rear == front,isEmpty方法实现如下:
public boolean isEmpty(){
return rear == front;
}
添加数据时,先判断队列是否已满。若未满,则将数据存入arr[rear % MAXSIZE],将rear向后移动一位。代码实现如下:
public void add(int date){
if (isFull()) {
throw new RuntimeException("队列已满,无法添加数据");
}
arr[rear % MAXSIZE] = date;
rear ++;
}
获取数据时,先判断队列是否为空。若非空,则将front向后移动,将arr[(front - 1) % MAXSIZE]取出。代码实现如下:
public int get(){
if (isEmpty()){
throw new RuntimeException("队列为空,无法获取数据");
}
front ++;
return arr[(front - 1) % MAXSIZE];
}
遍历队列,从front % MAXSIZE开始向后遍历,至(rear - 1) % MAXSIZE结束,代码实现如下:
public void show(){
if (isEmpty()){
System.out.println("队列为空");
return;
}
for (int i = front % MAXSIZE; i <= (rear - 1) % MAXSIZE; i ++){
System.out.println(arr[i]);
}
}