1.队列的介绍
(1)队列是一个有序列表,可以用数组或者链表来实现。
(2)遵循先进先出的原则。(先存入队列的数据先取出,后存入的数据后取出)
2.数组模拟队列
(1)因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front 及 rear 分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear 则是随着数据输入而改变
(2)存入数据时,有两种情况
1.将尾指针往后移一位,及rear+1,
2.若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。rear == maxSize - 1[队列满]
存入数据前应先判断队列是否已满
(3)取出数据时,有两种情况
1.正常取出,首指针后移一位,即front+1
2.若队列为空,则不能进行取出操作,即front==rear
(4)判断队列是否为空?
front==rear?相等则为空
(5)判断队列是否已满
Rear == maxSize -1?
该队列使用一次就不能再次使用,没有复用效果。
package datastructure.Queue;
/**
* @author xmz
* @content 数组模拟队列
*/
public class ArrayQueue {
//定义最大容量,头指针、尾指针、数组
private int maxSize;
private int front;
private int rear;
private int[] arr;
//创建队列构造器
//初始化队列
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
front = -1; //指向队列头部,front是指向队列头的前一个位置
rear = -1; //指向队列尾,指向队列的最后一个数据
}
//判断队列是否已满
public boolean isFull(){
return rear == maxSize - 1;
}
//判断队列是否为空
public boolean isEmpty(){
return front == rear;
}
//添加数据到队列
public void addQueue(int i){
//先判断队列是否已满
if(isFull()){
System.out.println("队列已满,无法进行添加");
return;
}
rear++;//rear后移
arr[rear] = i;
}
//获取队列的数据
public int getQueue(){
//判断队列是否为空
if (isEmpty()){
throw new RuntimeException("队列为空,无法取出数据");
}
front++;//front后移
return arr[front];
}
//显示队列所有数据
public void showQueue(){
//判断是否为空
if (isEmpty()){
System.out.println("队列为空,无数据");
return;
}
//遍历
for (int i = 0; i < arr.length; i++) {
System.out.printf("arr[%d] = %d\n",i,arr[i]);
}
}
//显示队列的头数据
public int headQueue(){
//判断是否为空
if (isEmpty()){
throw new RuntimeException("队列为空,无数据");
}
return arr[front+1];
}
}
3.循环队列
将数组看出一个环形,利用数组模拟环形队列。(通过取模的方式实现)
分析:
1)尾索引的下一个为头索引时表示队列满,将队列容量空出一个作为约定。
满足(rear+1)%maxSize == front,则表示队列已满。
2)rear == front 则表示队列为空。
package datastructure.Queue;
/**
* @author xmz
* @content 数组模拟循环队列
*/
public class CircleArrayQueue {
private int maxSize;
private int front;
private int rear;
private int[] arr;
//创建队列构造器
//初始化队列
public CircleArrayQueue(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
front = 0; //指向队列头部,front是指向队列头
rear = 0; //指向队列尾,指向队列的最后一个数据
}
//判断队列是否已满
public boolean isFull(){
return (rear+1) % maxSize == front;
}
//判断队列是否为空
public boolean isEmpty(){
return front == rear;
}
//添加数据到队列
public void addQueue(int i){
//先判断队列是否已满
if(isFull()){
System.out.println("队列已满,无法进行添加");
return;
}
//rear++;//rear后移
arr[rear] = i;
rear = (rear + 1) % maxSize;
}
//获取队列的数据
public int getQueue(){
//判断队列是否为空
if (isEmpty()){
throw new RuntimeException("队列为空,无法取出数据");
}
//front++;//front后移
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
//显示队列所有数据
public void showQueue(){
//判断是否为空
if (isEmpty()){
System.out.println("队列为空,无数据");
return;
}
//遍历
for (int i = front; i < front + size(); i++) {
System.out.printf("arr[%d] = %d\n",i % maxSize,arr[i % maxSize]);
}
}
//显示队列的头数据
public int headQueue(){
//判断是否为空
if (isEmpty()){
throw new RuntimeException("队列为空,无数据");
}
return arr[front];
}
public int size(){
return (rear + maxSize - front) % maxSize;
}
}