一:队列的基本概况:
// 队列是一个有序列表, 可以用【数组】或是【链表】去实现
// 原则: 先进先出 [即: 先存入队列的数据先取出,后存入的后取出
// 队列的输入和输出 是靠前后端来处理的,
利用 两个变量 :front 指向队列的前端, rear 指向队列的后端 ,
fornt 和 rear 随着 数据的入队和出队改变
二:有关环形队列的几个算法小公式:
rear 指向数组有效元素的下一个位置,初始值为 0;
front 指向数组的 第一个元素,初始值为0;
1.//判断数组元素是否已满:
2.// 在添加数据时,rear向后移位,指向有效元素的后一个位置,
rear = (rear + 1) % maxSize;
3.//在获取数据时 front 向后移位指向数组中有效的数据元素
front = (front + 1) % maxSize;
4.//得到数组中有效数据个数
三:代码如下:
测试类:
@SuppressWarnings("all")
public class Test {
public static void main(String[] args) {
CirCleArrayQueue_ queue = new CirCleArrayQueue_(4);
Scanner input = new Scanner(System.in);
boolean flage = true;
int elect = 0;
do {
System.out.println("1:--显示队列-- ");
System.out.println("2:--添加数据到队列--");
System.out.println("3:--从队列中取出数据--");
System.out.println("4:--得到队列的头数据--");
System.out.println("0: 退出程序");
System.out.println("请输入你的选择:");
elect = input.nextInt();
switch (elect) {
case 1:
queue.showQueue();
break;
case 2:
System.out.println("请输入你要添加的数据:");
int data = input.nextInt();
queue.addQueue(data);
break;
case 3:
// 对可能出现的异常进行 try catch 处理
try {
int getdata = queue.getQueueData();
System.out.printf("取出的数据是:%d\n", getdata);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 4:
try {
int headdata = queue.headQueueData();
System.out.printf("队列头的数据是:%d\n", headdata);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 0:
System.exit(0);
}
} while (flage);
}
}
功能实现类:
package data_structure_01.Queue.CirCleArrayQueue;
/**
* @author 不存在的骑士~
**/
/*环形队列*/
@SuppressWarnings("all")
public class CirCleArrayQueue_ {
private int maxSize; // 表示数组的最大容量
private int front; //front 的初始值是 0 front 指向 队列中的第一个元素
private int rear; //rear的初始值是 0 rear 指向的队列最后一个元素的最后一个位置,因为要空出一个位置做约定
private int[] arr; //该数组用于存放数据 = 要模拟的 队列
// 创建队列的构造器
public CirCleArrayQueue_(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
}
//判断队列是否已满
public boolean isFull() {
return (rear + 1) % maxSize == front;
//算法公式: 因为空出了一个位置,所以通过这个算法得到 队列是否已满
//举例: 比如 队列是长度为 5 , 那么在 rear 为 4 时就是队列满了,
// (4+1)%5 == 0
}
//判断队列是否为空
public boolean isEmpty() {
return front == rear;
}
// 添加数据到队列
public void addQueue(int n) {
//判断队列是否满
if (isFull()) {
System.out.println("队列已满,不可以加入数据~~");
return;
}
arr[rear] = n;
rear = (rear + 1) % maxSize; // 指向有效元素的后一个位置
//一个算法公式: 当我们要添加数据元素时,假如数组长度为5,数组为null,这时 front,rear 都指向下标为 0 的位置
// 我们向里面添加一个元素, 元素被加到数组下标为 0 的位置, rear指向的是 有效元素的下一个位置,rear 应指向 1
// (0+1)5 =1;
System.out.println("添加数据成功~~~");
}
// 获取队列的数据
public int getQueueData() {
// 判断队列是否为空
if (isEmpty()) {
// 队列为空,抛出一个异常
throw new RuntimeException("队列空,不能获取数据");
}
int queuedata = arr[front]; //先得到数组中的值
front = (front + 1) % maxSize; //front 向后移位
return queuedata; // 返回数组中的值
}
// 求出当前数组有效元素的个数
public int size() {
// 例子: rear = 2;
// front = 0;
// maxSise = 3;
// 有效元素个数是 (2+3-0)% 3 = 2
// rear 指向的有效元素的下一个元素,当 rear 为 3 时 数组下标 0,1 有数据
return (rear + maxSize - front) % maxSize;
}
//显示队列中的所有数据
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空,没有数据~~");
return;
}
for (int i = 0; i < size(); i++) {
System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
}
}
// 显示队列的头数据
public int headQueueData() {
if (isEmpty()) {
throw new RuntimeException("队列为空,没有数据~~");
}
return arr[front];
}
}