为解决普通队列在取出元素后当前位置无法再添加元素造成的空间浪费问题,提出环形队列,可重复的使用一段空间
还是使用数组模拟环形队列,定义指针front指向队列的第一个元素,rear指向队列最后一个元素的后一个位置
环形队列涉及一些取模算法,须认真琢磨
//数组模拟环形队列
class CircleQueue {
//队列的最大存储范围
private int maxSize;
//队列头部(注意front指向队列头部的元素)
private int front;
//队列尾部,指向队列的最后一个元素的下一个位置
private int rear;
//定义数组模拟队列
private int[] arr;
public CircleQueue(int maxSize) {
this.maxSize = maxSize;
rear = 0;//可以省略,默认也是0
front = 0;
//创建一个长度为maxSize的数组,即大小为maxSize的队列
arr = new int[maxSize];
}
//向队列中添加方法
//判断队列是否满
public boolean isFull() {
//rear指向最后一个元素的后一个位置
return (rear + 1) % maxSize == front;
}
//判断队列是否空
public boolean isEmpty() {
return front == rear;
}
//向队列中添加元素
public void addQueue(int num) {
//先判断队列是否满,如果满,则添加不了
if (isFull()) {
System.out.println("队列满,不能添加元素~~");
return;
}
//rear指向最后一个元素的后一个位置,因此先向rear所在位置添加一个元素,rear再后移
arr[rear] = num;
rear = (rear + 1) % maxSize;
}
//取出队列中的元素
public int getQueue() {
//取元素先判断队列是否为空,若为空,则不能取出数据
if (isEmpty()) {
throw new RuntimeException("队列空,不能取出数据~~");
//throw一个异常,程序也会终止,故不需要再return
}
//因为front指向队列的第一个元素,因此可直接取出front对应的元素,front再后移
//临时变量存储取出的值
int temp = arr[front];
//因为是环形队列,所以必须考虑取模,不能直接++
front = (front + 1) % maxSize;
return temp;
}
//显示队列中所有的元素
public void showQueue() {
//先判断队列是否为空,如果为空,则没有数据
if (isEmpty()) {
System.out.println("队列空,没有数据~~");
return;
}
//若不为空,取出队列中有效的元素
for (int i = front; i < front + size(); i++) {
//格式化输出
System.out.printf("arr[%d] = %d\n", (i + maxSize) % maxSize, arr[(i + maxSize) % maxSize]);
}
}
//编写方法拿到环形队列中有效元素的个数
public int size() {
return (rear - front + maxSize) % maxSize;
}
//显示队列的头元素
public int headQueue() {
//判断队列是否为空,若为空,则没有头元素
if (isEmpty()) {
throw new RuntimeException("队列空,没有头元素~~");
}
return arr[front];
}
}
public static void main(String[] args) {
char key = ‘ ‘;
boolean loop = true;
//创建一个实例化队列
CircleQueue queue = new CircleQueue(5);
//键盘扫描器
Scanner scanner = new Scanner(System.in);
while (loop) {
//简单界面模拟队列
System.out.println("========欢迎来到队列========");
System.out.println("s(show)显示队列元素:");
System.out.println("a(add)向队列添加元素:");
System.out.println("g(get)取出队列元素:");
System.out.println("e(exit)退出队列:");
System.out.println("h(head)显示队列头部元素:");
System.out.println("============================");
System.out.println("请输入你的选择:");
key = scanner.next().charAt(0);
switch (key) {
case ‘e‘:
loop = false;
break;
case ‘s‘:
try {
//showQueue方法抛出异常
queue.showQueue();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case ‘a‘:
System.out.println("请输入你要添加的元素:");
int num = scanner.nextInt();
queue.addQueue(num);
break;
case ‘g‘:
try {
//getQueue方法抛出异常
int res = queue.getQueue();
System.out.println("取出的元素为" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case ‘h‘:
try {
//headQueue方法抛出异常,需要捕获
int res = queue.headQueue();
System.out.println("队列头部元素为" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
}
}
System.out.println("程序退出~~");
}
原文:https://www.cnblogs.com/mx-info/p/14724900.html