Java使用数组模拟环形队列
一、数组模拟环形队列说明
1.这是对前面的数组模拟队列的优化,充分利用数组。因此将数组看看成一个环形的(通过取模的方式来实现即可)。
2.对环形队列进行分析说明:
(1)尾索引的下一个为头索引时表示队列已满,即将队列容量空出一个作为一个约定,这个在做队列满的时候需要注意(rear+1)%maxSize=front为队列满的判定条件
(2)rear=front还是环形队列为空的判定条件
二、代码实现
import java.util.Scanner;
public class CircleArrayQueueDemo {
public static void main(String[] args) {
//测试一把
System.out.println("测试数组模拟环形队列的案例~~");
//创建一个数组队列
CircleArray circleArray=new CircleArray(4);//说明4:其队列的有效数据最大为3
char key=' '; //接收用户输入
Scanner scanner=new Scanner(System.in);
boolean loop=true;
//输出一个菜单
while(loop){
System.out.println("s(show):显示队列");
System.out.println("e(exit):退出程序");
System.out.println("a(add):添加数据到队列");
System.out.println("g(get):从队列取出数据");
System.out.println("h(head):查看队列头的数据");
key=scanner.next().charAt(0); //接收一个字符
switch (key) {
case 's':
circleArray.showQueue();
break;
case 'e':
scanner.close();
loop=false;
break;
case 'a':
System.out.println("请输入一个数:");
int value=scanner.nextInt();
circleArray.addQueue(value);
break;
case 'g':
try {
int res=circleArray.getQueue();
System.out.printf("取出的数据是%d\n",res);
}
catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'h'://查看队列头的数据
try {
int res=circleArray.headQueue();
System.out.printf("输出队列头的数据是%d\n",res);
}
catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
//创建一个模拟环形数组的类
class CircleArray{
private int maxSize;//表示数组的最大容量
//front变量的含义做一个调整:front就指向队列的第一个元素,也就是说arr[front]就是队列的第一个元素,front的初始值为0
private int front;
//rear变量的含义做一个调整:rear指向队列的最后一个元素的后一个位置,目的是:希望空出一个空间作为约定,real的初始值为0
private int rear;
private int[] arr;//该数据用于存放数据,模拟队列
//构造器
public CircleArray(int arrMaxSize){
maxSize=arrMaxSize;
arr=new int[maxSize];
front=0;
rear=0;
}
//判断队列是否满
public boolean isFull() {
return (rear+1) % maxSize==front;
}
//判断队列是否为空
public boolean isEmpty() {
return front==rear;//当队列的头部和队列的尾部相等的时候,此时队列就是为空的
}
//添加数据到队列中
public void addQueue(int n) {
//判断队列是否满了
if (isFull()) {
System.out.println("队列已满,不能加入数据!");
return;
}
//直接将数据加入就可以了
arr[rear]=n;
//将real后移
rear=(rear+1) % maxSize;
}
//获取队列的数据,数据出队列
public int getQueue() {
//判断队列是否为空,队列为空不能出队列
if (isEmpty()) {
throw new RuntimeException("队列空,不能取数据");
}
//这里需要分析出front是指向队列的第一个元素
//1.先把front对应的值保存到一个临时变量中
//2.将front后移,考虑取模
//3.将临时保存的变量返回
int value=arr[front];
front=(front+1) % maxSize;
return value;
}
//显示队列的所有数据
public void showQueue() {
//遍历数组
if (isEmpty()) {
System.out.println("队列是空的,没有数据~");
return;
}
//思路:从front开始遍历,遍历多少个元素
for(int i=front;i<front + size();i++){
System.out.printf("arr[%d]=%d\n",i % maxSize,arr[i % maxSize]);
}
}
//求出当前队列有效数据的个数,否则无法遍历队列的所有数据
public int size(){
//比如rear=1,front=0,maxSize=3 此时有效数字为1
return (rear+maxSize-front) % maxSize;
}
//显示队列的头数据,注意这不是取出头部数据
public int headQueue(){
//判断队列是否为空
if (isEmpty()) {
throw new RuntimeException("队列是空的,没有数据~");
}
return arr[front];
}
}
三、测试代码,如下图所示: