本文接着上一篇博文继续扩展,这次讲的是数组模拟环形队列。https://blog.csdn.net/Hello_ChenLiYan/article/details/107273124
一、用数组模拟队列时,要考虑到复用的效果,所以用环形队列来表示
二、数组模拟环形队列中 往队列里添加数据 思路:
- 先判断队列是否为满,
(rear+1) % maxSize = front
- 将数据加入队列,
arr[rear]=n
- 将队尾指针往后移,rear要取模,
rear = (rear+1) % maxSize
三、 往队列里取出数据 思路:
- 先判断队列是否为空,
rear == front
- 将front位置的值存放到临时变量中,
int value = arr[front]
- 将队首指针front往后移,要取模,
front = (front+1)%maxSize
- 返回临时变量,
return value
四、队列有效数据个数
(rear + maxSize - front) % maxSize
五、显示队列所有数据
- 先判断队列是否为空,如果为空,则显示没有数据
- 显示队列所有数据要从以front开始,直到front + 队列的有效数据个数,进行遍历
for (int i = front; i < front+size(); i++) {
System.out.printf("队列数据为 arr[%d] = %d\n",(i % maxSize),arr[(i % maxSize)]);
六、代码实现
front:队列第一个位置
rear:队列的最后一个数据的后一个位置
package com.queue;
import java.util.Scanner;
import javax.management.RuntimeErrorException;
public class CircleArrayQueueDemo {
public static void main(String[] args) {
CircleArrayQueue circleArrayQueue = new CircleArrayQueue(4);
char key = ' ';
Scanner scanner = new Scanner(System.in);
boolean loop = true;
while(loop) {
System.out.println("s(show):显示队列所有数据");
System.out.println("a(add):往队列添加数据");
System.out.println("g(get):往队列获取数据");
System.out.println("h(head):获取队列头数据");
System.out.println("e(exit):退出程序~");
key = scanner.next().charAt(0);
switch (key) {
case 's':
circleArrayQueue.showQueue();
break;
case 'a':
System.out.println("请输入你要添加到队列的数据");
int n = scanner.nextInt();
circleArrayQueue.addQueue(n);
break;
case 'g':
try {
int res = circleArrayQueue.getQueue();
System.out.printf("取出的队列数据为%d\n",res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
int res = circleArrayQueue.headQueue();
System.out.printf("队列的头数据为%d\n",res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'e':
scanner.close();
loop = false;
System.out.println("退出程序~");
break;
default:
break;
}
}
System.out.println("程序完全退出~~");
}
}
class CircleArrayQueue {
private int maxSize;//队列最大值
private int front ;//队首,队列的前一个位置
private int rear ;//队尾,队列的最后一个位置
private int[] arr;//数组
public CircleArrayQueue (int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
rear = 0;
front = 0;
}
//判断队列是否为空
public boolean isEmpty() {
return rear == front;
}
//判断队列是否满
public boolean isFull() {
// rear:队列后一个位置,预留一个空位作为动态变化
return (rear+1) % maxSize == front;
}
//往队列添加数据
public void addQueue(int n) {
if (isFull()) {
System.out.println("队列满了,不能添加数据了~~");
return ;
}
//将数据加入队列
arr[rear]=n;
//rear取模,rear:队列后一个位置
rear = (rear+1) % maxSize;
}
//往队列获取数据,即取出
public int getQueue() {
if (isEmpty()) {
throw new RuntimeErrorException(null,"队列为空,不能取数据");
}
//将front位置的值存放到临时变量中
int value = arr[front];
//front往后移,要取模
front = (front+1)%maxSize;
//返回临时变量
return value;
}
//获取队列头数据
public int headQueue() {
if (isEmpty()) {
throw new RuntimeErrorException(null,"队列为空,不能取数据");
}
//front是队列的第一个位置
return arr[front];
}
//显示队列所有数据
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),arr[(i % maxSize)]);
}
}
//获取队列的有效数据
public int size() {
//rear = 1
//front = 0
//maxSize = 4
return (rear + maxSize - front) % maxSize;
}
}
七、数组模拟环形队列,达到了一种复用的效果,取出数据后,可以往队列里添加数据,同时 front 和 rear 也会动态变化。