前面利用数组模拟队列,但是有一个问题,那就是队列只能使用一次,不能达到复用。 所以,将这个队列加以改进,改进为一个循环队列,来充分利用数组。 可以将数组看做一个环形的(通过取余数的方式来实现)
思路分析
- front指向队列的第一个元素,初始值为0
- rear指向队列的最后一个元素的写一个位置,rare不存值,初始值为0
这个队列的有效数据个数最大师size-1,也就是说数组的rare索引处是没有值得,因为如果rare存值的话,当队列只有rare一个空间的时候,存完值后rare=front,此时无法判断队列为空或满
- 当队列满的时候,判断条件是(rare+1)%size=front
- 当队列为空时,判断条件为rare==front
- 队列中有效数据的个数为 (rare+size-front)%size
- 通过这些条件就可以得到一个环形队列
代码实现:
1. 新建CircleArray类,定义成员变量
class CircleArray {
private int arr[];
private int maxSize;
private int rear;//队尾默认为0,指向最后一个元素的下一个位置
private int front;//队头默认为0,指向队列第一个元素
}
2. 定义构造方法,需要传入一个maxsize的值,这个值为数组长度
public CircleArray(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
}
3. 定义判断队列是否为满的方法
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
- 定义判断队列是否为空的方法
public boolean isEmpty() {
return rear == front;
}
5. 定义添加元素的方法(判断不为满,之后添加到rare的索引位置,rare后移一位)
public void addQueue(int value) {
if (isFull()) {
System.out.println("队列为满,不能添加");
return;
}
arr[rear] = value;
rear = (rear + 1) % maxSize;
}
6. 定义取出元素的方法(判断不为空,之后将front位置的元素取出,然后front后移一位)
public int removeQUeue() throws Exception {
if (isEmpty()) {
throw new Exception("队列为空,不能取数据");
}
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
7. 定义展示队列的方法
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空,没有数据");
}
for (int i = front; i < front + ((rear + maxSize - front) % maxSize); i++) {
//(rear + maxSize - front) % maxSize为数组的有效数据的个数
System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
//i%maxSize保证能挣确拿到队列元素
}
}
8. 定义获得队列头的方法***
public int headQueue() throws Exception {
if (isEmpty()) {
throw new Exception("队列为空,没有数据");
}
return arr[front];//头元素就是front索引指向位置的元素
}
9. 测试(新建一个circleArray类)
public static void main(String[] args) throws Exception {
CircleArray circleArray = new CircleArray(3);
Scanner sc = new Scanner(System.in);
boolean loop = true;
while (loop) {
System.out.println("s(show):显示队列");
System.out.println("e(exit):退出队列");
System.out.println("a(add):添加数据到队列");
System.out.println("g(get):从队列中取出数据");
System.out.println("h(head):查看队列头的数据");
String next = sc.next();
switch (next) {
case "s":
circleArray.showQueue();
break;
case "a":
System.out.println("请输入一个数");
int i = sc.nextInt();
circleArray.addQueue(i);
break;
case "g":
try {
int res = circleArray.removeQUeue();
System.out.println("取出的数据是 " + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "h":
try {
int res = circleArray.headQueue();
System.out.println("队列头数据是" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "e":
sc.close();
loop = false;
break;
}
}
System.out.println("程序退出");
}
完整代码:
package com.xx.queue;
import java.util.Scanner;
/**
* @Author: Jeffery
* @CreateTime: 2019-09-24 16:54
*/
public class CircleArrayQueueDemo {
public static void main(String[] args) throws Exception {
CircleArray circleArray = new CircleArray(3);
Scanner sc = new Scanner(System.in);
boolean loop = true;
while (loop) {
System.out.println("s(show):显示队列");
System.out.println("e(exit):退出队列");
System.out.println("a(add):添加数据到队列");
System.out.println("g(get):从队列中取出数据");
System.out.println("h(head):查看队列头的数据");
String next = sc.next();
switch (next) {
case "s":
circleArray.showQueue();
break;
case "a":
System.out.println("请输入一个数");
int i = sc.nextInt();
circleArray.addQueue(i);
break;
case "g":
try {
int res = circleArray.removeQUeue();
System.out.println("取出的数据是 " + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "h":
try {
int res = circleArray.headQueue();
System.out.println("队列头数据是" + res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "e":
sc.close();
loop = false;
break;
}
}
System.out.println("程序退出");
}
}
class CircleArray {
private int arr[];
private int maxSize;
private int rear;//队尾默认为0,指向最后一个元素的下一个位置
private int front;//队头默认为0,指向队列第一个元素
public CircleArray(int maxSize) {
this.maxSize = maxSize;
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;
}
public int removeQUeue() throws Exception {
if (isEmpty()) {
throw new Exception("队列为空,不能取数据");
}
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空,没有数据");
}
for (int i = front; i < front + ((rear + maxSize - front) % maxSize); i++) {
System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
}
}
public int headQueue() throws Exception {
if (isEmpty()) {
throw new Exception("队列为空,没有数据");
}
return arr[front];
}
}