思路如下:
1、front变量的含义做一个调整:front就指向队列的第一个元素,
也就是说arr[front]就是队列的第一个元素,front的初始值为0
2、rear变量的含义做一个调整:rear指向队列的最后一个元素的最后一个位置,
因为希望空出一个空间作为约定,rear的初始值为0
3、当队列满时,条件是:(rear+1)%maxSize==front,因为rear+1是预留一个位置,
不牺牲这个空间会导致无法判断队列是空还是满,rear一直自增,也就是说rear是
很有可能大于maxSize的,这里%一下rear,是为了可以获得rear在环形队列上的真实位置,
比如maxSize=5,rear=10,因为rear被加到10,此时rear的实际位置是0.
4、队列为空的条件:front=rear
5、队列中有效的数据的个数:(rear+maxSize+front)%maxSize
package com.wrx.dataStructures.queue;
import java.util.Scanner;
/**
* @auther wrx
* @time 2022-09-17-8:32
*/
/*数组模拟环形队列的实现:
思路如下:
1、front变量的含义做一个调整:front就指向队列的第一个元素,
也就是说arr[front]就是队列的第一个元素,front的初始值为0
2、rear变量的含义做一个调整:rear指向队列的最后一个元素的最后一个位置,
因为希望空出一个空间作为约定,rear的初始值为0
3、当队列满时,条件是:(rear+1)%maxSize==front,因为rear+1是预留一个位置,
不牺牲这个空间会导致无法判断队列是空还是满,rear一直自增,也就是说rear是
很有可能大于maxSize的,这里%一下rear,是为了可以获得rear在环形队列上的真实位置,
比如maxSize=5,rear=10,因为rear被加到10,此时rear的实际位置是0.
4、队列为空的条件:front=rear
5、队列中有效的数据的个数:(rear+maxSize+front)%maxSize
*/
public class CircleArrayQueueDemo {
public static void main(String[] args) {
CircleArray arrayQueue = new CircleArray(3);
Scanner sc=new Scanner(System.in);
char key=' ';//接受用户输入
boolean loop=true;
while (loop){
System.out.println("输入s,表示显示队列");
System.out.println("输入e,表示退出程序");
System.out.println("输入a,表示添加数据到队列");
System.out.println("输入g,表示从队列中取出数据");
System.out.println("输入h,表示查看队列头的数据");
System.out.println("请输入选项:");
key=sc.next().charAt(0);//接收一个字符
switch (key){
case 's'://显示队列
arrayQueue.showQueue();
break;
case 'a'://添加数据到队列
System.out.println("请输入一个数");
int value=sc.nextInt();
arrayQueue.addQueue(value);
break;
case 'g'://从队列中取出数据
try {
int res=arrayQueue.getQueue();
System.out.println("取出的数据是:"+res);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case 'h'://查看队列头的数据
try {
int res=arrayQueue.headQueue();
System.out.println("队列头的数据为"+res);
} catch (Exception e) {
throw new RuntimeException(e);
}
break;
case 'e':
sc.close();
loop=false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class CircleArray{
private int maxSize;//表示数组的最大容量
private int front;//队列头
private int rear;//队列尾
private int[] arr;//该数组用于存放数据,模拟队列
//创建队列的构造器
public CircleArray(int arrMaxSize) {
maxSize=arrMaxSize;
arr=new int[maxSize];
front=0;//指向队列头部,分析出front是指向队列头的前一个位置
rear=0;//指向队列尾,指向队列尾的数据(即就是队列最后一个数据)
}
//判断队列是否满
public boolean inFull(){
return (rear+1)%maxSize==front;
}
//判断队列是否为空
public boolean isEmpty(){
return rear==front;
}
//添加数据到队列
public void addQueue(int n){
//判断队列是否已满
if(inFull()){
System.out.println("队列已满,无法再添加数据");
return;
}
//直接将数据加入
arr[rear]=n;
rear=(rear+1)%maxSize;
}
//获取队列的数据,输出队列
public int getQueue(){
if(isEmpty()){
//通过抛出异常终止运行
throw new RuntimeException("队列为空,不能取数据");
}
/*1、先把front对应的值保留到一个临时变量
2、将front后移,考虑取模
3、将临时保存的变量返回
*/
int value=arr[front];
front=(front+1)%maxSize;
return value;
}
//显示队列的所有数据
public void showQueue(){
if(isEmpty()){
System.out.println("队列为空,无法显示数据");
}
for (int i=front;i<front+size();i++){
System.out.println("arr["+i%maxSize+"]="+arr[i%maxSize]);
}
}
//求出当前队列有效数据的个数
private int size(){
return (rear+maxSize+front)%maxSize;
}
//显示队列的头数据,注意不是取出数据
public int headQueue(){
if(isEmpty()) {
throw new RuntimeException("队列为空,不能取数据");
}
return arr[front];
}
}