基本介绍
数组模拟队列
思路分析
代码实现
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 创建一个队列
ArrayQueue queue = new ArrayQueue(3);
int select;
Scanner scanner = new Scanner(System.in);
boolean loop = true;
while (loop) {
System.out.println("\n----------队列操作菜单-----------");
System.out.println("1、查看队列");
System.out.println("2、添加数据到队列");
System.out.println("3、取出队列元素");
System.out.println("4、退出菜单");
System.out.println("请选择:");
select = scanner.nextInt();
switch (select) {
case 1: {
queue.showQueue();
break;
}
case 2: {
System.out.println("请输入要添加的数据(数字类型):");
int data = scanner.nextInt();
queue.pushQueue(data);
break;
}
case 3: {
try {
int data = queue.popQueue();
System.out.println("队头元素为:" + data);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
}
case 4: {
loop = false;
break;
}
}
}
scanner.close();
}
}
// 用数组模拟队列
class ArrayQueue {
private int maxSize; // 队列的最大容量
private int front; // 队头指针
private int rear; // 队尾指针
private int[] queue; // 队列,用于存储数据,此处用数组模拟
ArrayQueue(int maxSize) {
// 初始化数据
this.maxSize = maxSize;
// 根据 maxSize 创建一个队列
this.queue = new int[maxSize];
// 初始让队头队尾为 -1
this.front = -1; // front 指向队头的前一个位置,若为 0 则指向队头那一个位置
this.rear = -1; // rear 指向队尾的位置
}
// 队列判空
public boolean isEmpty() {
return front == rear;
}
// 队列判满
public boolean isFull() {
return rear == maxSize - 1;
}
// 入队
public void pushQueue(int data) {
// 先判断队列是否满了
if (isFull()) {
System.out.println("队列已满,不能添加数据了");
return;
}
rear++; // 移动队尾指针,指向后一个空的位置
queue[rear] = data; // 向该空的位置添加数据,此时 rear 依旧指向队尾最后一个数据
}
// 出队
public int popQueue() {
// 先判断队列是否为空
if (isEmpty()) {
throw new RuntimeException("队列为空,不能获取数据");
}
// 此时 front 指向后一个位置,该位置是要被取出数据的位置
// 数据取出后相当于队列移除该数据了,所以 front 仍然指向队头位置的前一个位置
front++;
return queue[front];
}
// 打印队列
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空...");
return;
}
System.out.println("队列元素为:");
for (int i = front + 1; i <= rear; i++) {
System.out.printf(queue[i] + "\t");
}
System.out.println();
}
}
数组模拟环形队列
在上一个实现中,数组使用一次就不能再使用,没有达到复用效果,造成空间的浪费。
思路分析
代码实现
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 创建一个队列
// 因为有一个位置是用于判断队列是否为满,即不存储具体数据,所以实际队列容量为 4-1=3
CircleArrayQueue queue = new CircleArrayQueue(4);
int select;
Scanner scanner = new Scanner(System.in);
boolean loop = true;
while (loop) {
System.out.println("\n----------队列操作菜单-----------");
System.out.println("1、查看队列");
System.out.println("2、添加数据到队列");
System.out.println("3、取出队列元素");
System.out.println("4、退出菜单");
System.out.println("请选择:");
select = scanner.nextInt();
switch (select) {
case 1: {
queue.showQueue();
break;
}
case 2: {
System.out.println("请输入要添加的数据(数字类型):");
int data = scanner.nextInt();
queue.pushQueue(data);
break;
}
case 3: {
try {
int data = queue.popQueue();
System.out.println("队头元素为:" + data);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
}
case 4: {
loop = false;
break;
}
}
}
scanner.close();
}
}
// 用数组模拟环形队列
class CircleArrayQueue {
private int maxSize; // 队列的最大容量
// front 指向队列的第一个元素,也就是说 queue[front] 就是队列的第一个元素
// front 的初始值为 0
private int front; // 队头指针
// rear 指向队列的最后一个元素的后一个位置,因为希望空出一个位置作为判断队列是否为满的标志
// rear 的初始值为 0
private int rear; // 队尾指针
private int[] queue; // 队列,用于存储数据,此处用数组模拟
CircleArrayQueue(int maxSize) {
// 初始化数据
this.maxSize = maxSize;
// 根据 maxSize 创建一个队列
this.queue = new int[maxSize];
// 初始让队头队尾为 0,也可以不写,因为成员变量默认值就是为 0
this.front = 0;
this.rear = 0;
}
// 队列判空
public boolean isEmpty() {
return front == rear;
}
// 队列判满
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
// 入队
public void pushQueue(int data) {
// 先判断队列是否满了
if (isFull()) {
System.out.println("队列已满,不能添加数据了");
return;
}
// 因为 rear 本身就指向队列最后一个元素的后一个位置,所以可以直接将数据加入
queue[rear] = data;
// 将 rear 后移,需要取模,因为可能数组前面是可利用的空间,把 rear 指向前面空的位置
rear = (rear + 1) % maxSize;
}
// 出队
public int popQueue() {
// 先判断队列是否为空
if (isEmpty()) {
throw new RuntimeException("队列为空,不能获取数据");
}
// front 指向队列的第一个元素
// 先把 front 对应的值用一个临时变量存储
// 将 front 后移,需要取模
// 将临时变量返回
int val = queue[front];
front = (front + 1) % maxSize;
return val;
}
// 打印队列
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空...");
return;
}
System.out.println("队列元素为:");
int size = queueSize();
for (int i = front; i < front + size; i++) {
System.out.printf(queue[i % maxSize] + "\t");
}
System.out.println();
}
// 求出当前队列有效数据的个数
public int queueSize() {
return (rear + maxSize - front) % maxSize;
}
}