环形队列的介绍:
- 队列是一个有序列表,可以用数组或是链表来实现。
- 遵循先入先出的原则。即:先存入队列的数据,要先取出,后存入的要后取出。
模拟步骤:
- 声明数组,且最大容量为maxSize。
- 因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front 及 rear 分别记录队列前后端的下标, front 会随着数据输出而改变,而 rear 则是随着数据输入而改变。
- front指向队列的第一个元素,初始值为0。
- rear指向队列的最后一个元素的后一个位置,初始值为0。
注意:
1.队列满的条件为 (rear + 1)% maxSize == front;(这里是在数组的最有一个位置空出来做约定)
2.队列空的条件为 rear == front;
3.队列中有效数据的个数是(rear + maxSize - front)%maxSize
4.在front和rear后移的过程中也需要取模,这才能达到循环的效果
rear = (rear + 1) % maxSize;//环形队列rear指针后移
front = (front + 1) % maxSize;//环形队列front指针后移
具体的实现代码是:
package Queue;
import java.util.Scanner;
public class CircleArrayQueue {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);//声明输入对象
System.out.println("输入队列数组的长度");//输入数组队列长度
int length = sc.nextInt();
CircleArray circleArray = new CircleArray(length);//创建长度为length的队列
boolean loop = true;
while (loop){
System.out.println("请输入一个字母");
System.out.println("a(添加数值)");
System.out.println("g(取出数值)");
System.out.println("s(展示所有数值)");
System.out.println("h(取出头数值)");
System.out.println("l(队列有效长度)");
System.out.println("e(退出选择)");
String key = sc.next();//接收选择
switch (key){//判断调用的方法
case "a":
System.out.println("请输入数值");
int value = sc.nextInt();
circleArray.addQueue(value);//调用并传递数值
break;
case "g":
circleArray.getQueue();//调用取出数值方法
break;
case "s":
circleArray.showQueue();//调用展示所有数值方法
break;
case "h":
circleArray.headQueue();//调用取出头数值方法
break;
case "l":
circleArray.size();//调用队列有效长度方法
break;
case "e":
loop = false;
break;
default:
break;
}
}
}
}
class CircleArray{
private int maxSize;//声明数组的最大值
private int front;//头指针 -> 指向数组的第一个元素
private int rear;//尾指针 -> 指向数组最后一个元素的最后一个位置
private int[] arr;//定义一个数组接收数据
public CircleArray(){//无参构造
}
public CircleArray(int maxArraySize){//有参构造
maxSize = maxArraySize;
arr = new int[maxSize];//声明数组
}
public Boolean isFull(){//队列满的条件
return (rear + 1) % maxSize == front;
}
public Boolean isEmpty(){//队列空的条件
return rear == front;
}
public void addQueue(int value){//添加数据
if(isFull()){//判断是否满
System.out.println("数组满,不能添加数据");
return;
}
arr[rear] = value;//赋值
rear = (rear + 1) % maxSize;//rear后移
}
public void getQueue(){//取出数据
if(isEmpty()){//判断是否空
System.out.println("数组空,不能取数据");
return;
}
System.out.printf("arr[%d]=%d",front,arr[front]);//格式输出数值
front = (front + 1) % maxSize;//front后移
}
public void showQueue(){//展示数据
int front1 = front;//利用中间值遍历队列
while (!isEmpty()){
System.out.printf("arr[%d]=%d\n",front1,arr[front1]);//格式输出队列的值
front1 = (front1 + 1) % maxSize;//front后移
}
}
public void headQueue(){//头数据
if(isEmpty()){//判断队列是否为空
System.out.println("数组为空,不能取数据");
return;
}
System.out.printf("arr[%d]=%d",front,arr[front]);//格式输出队列的值
}
public int size(){//有效数据的个数
return (rear + maxSize - front) % maxSize;
}
}