图中展示了两种情况下的指针变化(注意两个指针的值一直在递增的,可能会大于size)
代码实现:(解说见注释)
/**
* 主类,用于提供主方法
*
* @author hanj.cn @outlook.com
*/
public class QueueTest {
public static void main(String[] args) {
Queue queue = new Queue(5);
boolean bool = true;
while (bool) {
System.out.print("\n请输入指令:");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
switch (input) {
case "f":
if (queue.isFull()) {
System.out.println("队列已满");
} else {
System.out.println("队列未满");
}
break;
case "i":
queue.info();
break;
case "e":
if (queue.isEmpty()) {
System.out.println("队列为空");
} else {
System.out.println("队列不为空");
}
break;
case "w":
queue.getWholeQueue();
break;
case "g":
queue.getQueue();
break;
case "a":
Scanner scanner1 = new Scanner(System.in);
String string = scanner1.nextLine();
queue.add(string);
break;
case "q":
System.out.println("成功退出~~~");
bool = false;
break;
default:
System.out.println("输入有误");
break;
}
}
}
}
/**
* 一个用来模拟队列的类
*/
class Queue {
// 数组大小
private final int size;
// 头指针,指向第一个元素的位置,初始化为0
private int front;
// 尾指针,指向最后一个元素的下一个位置,初始化为0
private int rear;
// 维护的数组
private final String[] array;
/**
* 初始化
*
* @param size the size
*/
public Queue(int size) {
this.size = size;
this.array = new String[size];
}
/**
* 判断队列是否为空
*
* @return the boolean
*/
public boolean isEmpty() {
// 由图可知, rear = front 时,队列为空,注意 front <= rear 是一直成立的,并且 rear - front <= size - 1 也是成立的
return rear == front;
}
/**
* 判断数组是否已经满了
*
* @return the boolean
*/
public boolean isFull() {
// 由于我们判断数组是否为空的条件是 rear == front 所以为了区分这两种情况,规定 rear 始终指向最后一个元素的下一个位置,这就导致一个问题,最后一个位置是无法填充元素的,即队列最大可用容量为最大容量减一
return ((rear + 1) - front) % size == 0;
}
/**
* 添加元素
*
* @param string the string
*/
public void add(String string) {
if (!isFull()) {
// 注意此处的 ++rear ,前"++"确保了 rear 指针的位置始终在最后一个元素的后面
array[((++rear) - 1) % size] = string;
System.out.printf("添加:%s 成功\n", string);
return;
}
System.out.println("队列已满");
}
/**
* 获取 front 指针指向的数据
*/
public void getQueue() {
if (!isEmpty()) {
// 注意此处的 front++ ,这完成了 front 指针的后移
System.out.printf("取出:%s\n", array[(front++) % size]);
return;
}
System.out.println("队列为空");
}
/**
* 取出所有有效的数据
*/
public void getWholeQueue() {
if (!isEmpty()) {
System.out.println("全部数据如下:");
for (int i = front % size; i <= (rear - 1) % size; i++) {
System.out.printf("%s\t", array[i]);
}
System.out.println();
return;
}
System.out.println("队列为空");
}
/**
* 获取此时两个指针的位置
*/
public void info() {
System.out.printf("front = %d, rear = %d\n", front, rear);
}
}