实现原理:
代码实现:
package com.guigu.queue;
import java.util.Scanner;
/**
* @author AZ
* @describe 用数组实现的环形队列
*/
public class QueueDemo02 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入队列的长度:");
int maxSize = scanner.nextInt();
ArrayQueue arrQueue = new ArrayQueue(maxSize);
boolean isFlag = true; //用来控制程序退出
char key = ' '; //用来接收命令
while(isFlag) {
System.out.println("a(添加数据)");
System.out.println("s(展示队列数据)");
System.out.println("e(退出程序)");
System.out.println("h(获得队首数据)");
System.out.println("g(取出数据)");
System.out.println("请选择你要执行的操作:");
key = scanner.next().charAt(0);
switch(key) {
case 'a':
System.out.println("请输入一个整数:");
int value = scanner.nextInt();
arrQueue.addQueue(value);
break;
case 's':
arrQueue.showQueue();
break;
case 'e':
isFlag = false;
break;
case 'h':
try {
int headValue = arrQueue.getHeadValue();
System.out.println("队首元素为:" + headValue);
break;
} catch (Exception e) {
System.out.println(e);
}
case 'g':
try {
int getValue = arrQueue.getQueue();
System.out.println("取出元素:" + getValue);
break;
} catch (Exception e) {
System.out.println(e);
}
}
}
System.out.println("程序结束!!");
}
}
//定义一个队列的实现类,
class ArrayQueue{
private int rear = 0; //队尾指针,初始化为0
private int front = 0; //队首指针,初始化为0
private int maxSize; //表示队列的容量
private int[] queueData; //定义一个数组,用来存放队列的数据
//构造器,初始化一个队列
public ArrayQueue(int queueSize) {
this.maxSize = queueSize;
this.queueData = new int[maxSize];
}
//插入元素,进队
public void addQueue(int value) {
//判断队列是否为满
if(isFull()) {
System.out.println("队列已满~~");
return;
}
queueData[rear] = value; //rear当前所指位置就是待插入位置
rear = (rear + 1) % maxSize; //rear往后移一位
}
//取出数据,出队
public int getQueue() {
//判断队列是否为空
if(isEmpty()) {
throw new RuntimeException("队列为空~~"); //因为方法有返回值,所以抛个异常
}
int value = queueData[front];
front = (front + 1) % maxSize;
return value;
}
//遍历队列
public void showQueue() {
//判断队列是否为空
if(isEmpty()) {
System.out.println("队列为空~~");
return;
}
//有几个有效值就循环几次
for(int i = front;i < front + getSize();i++) {
System.out.printf("Queue[%d]=%d \n", i, queueData[i]);
}
}
//获取队首元素
public int getHeadValue() {
if(isEmpty()) {
throw new RuntimeException("队列为空~~");
}
return queueData[front];
}
//判断队列中的有效元素个数
public int getSize() {
return (rear + maxSize - front) % maxSize;
}
//判断队列是否为空
public boolean isEmpty() {
return rear == front; //当队首指针和队尾指针相等时,说明队列为空
}
/**
* 可能有人会好奇,为什么rear == front时是队列为空,而不是队列为满?
* 其实呢,当rear与front相等时, 这两种意思都可以表示
* 所以在rear与front相等时避免有歧义,在此呢我选择浪费一个内存空间来消除歧义
* 就是当rear和front相等时,就认为是队列为空,当rear+1和front相等时认为队列为满
* 此时始终让rear始终指向队尾元素的后一个位置,也就是待插入元素的位置
*/
//判断队列是否已满
public boolean isFull() {
return (rear + 1 + maxSize) % maxSize == front; //此时说明队列已满
}
}
总结: 思路并不太难,主要是理解rear和front相等时歧义的消除。如果对为什么每次移动rear和front都 取模以及判断有效值个数的时候的取模等操作不太理解,就画图看下,你就懂了。