循环队列的结构:
private Integer maxSize; // 队列的最大数量
private Integer front; // 队列的头
private Integer rear; // 队列的尾
private int[] arr; // 定义数组用于存放数据
循环队列的初始化:
若使其为循环队列,则队列的头指向队列的第一个也就是front = 0;
队列的尾指向队列的第一个元素的下一个,初始化时没有元素,所以第一个元素的下一位也是0,即rear = 0;
构造函数为:
public ArrayQueue2(Integer maxSize) {
this.maxSize = maxSize; // 给最大值赋值
arr = new int[this.maxSize]; // 初始化数组
front = 0;
rear = 0; // 循环指针都为零
}
判断队列是否满的条件:
当使用循环队列时我们要拿出一个空间作为连接点,当然这个连接点也是动态的,也就是以一个空间为代价换取其它空间的重复使用。
判断是否满的表达式是:(队列尾指针 + 1) % 队列最大长度 == 队列头指针;
也就是:(rear + 1) % maxSize == front;
原因:maxSize是表示队列的长度,假如是4,那数组下标是按照0--3的也就是rear和front最大只能到3,之后又重新为0。前面也说过要拿出一个空间作为连接点,这个连接点是动态的,所以消耗一个空间,maxSize是4,则最大只能存放3个空间的数据;
public boolean isFull() {
return (rear + 1) % maxSize == front; // 判断是否满了
}
判断是否为空:
当队列中未添加数据时为空,此时rear和front都处于0位置,即rear == front;
public boolean isEmpty() {
return rear == front; // 判断是否为空(指针无移动)
}
判断有效数据个数:
表达式:(队列尾指针 + 队列长度 - 队列头指针) % 队列的长度;
即:(rear + maxSize - front) % maxSize;
普通的队列有效数据个数:(rear - front)就可以了
但是这里是循环队列,rear到达maxSize - 1时,取出第一个数据,arr[0]空出来,rear的下一个位置将是0; 此时的0 - front就是一个负数,当我们加上maxSize的时候就可以放心的去减去front;
// 展示所有数据
public void show() {
if(isEmpty()) {
System.out.println("队列为空,无法编列");
return;
}
for(int i = 0; i < (rear + maxSize - front) % maxSize; i++) {
System.out.println("arr["+ (front + i) +"]=" + arr[front + i]);
}
}
存放数据:
为了保证在rear到达maxSize - 1时候,下一次移动到0的位置,我们则需要
将rear = (rear + 1) % maxSize;
// 添加数据
public void addQueue(Integer data){
if(isFull()) {
System.out.println("队列已满,无法添加数据!");;
return;
}
arr[rear] = data;
rear = (rear + 1) % maxSize;
}
拿出数据:
此时同理:为了保证在front到达maxSize - 1时候,下一次移动到0的位置,我们则需要
将front= (front+ 1) % maxSize;
拿出头数据是为了方便我们观察队列的变化;
// 拿出数据
public int getQueue(){
if(isEmpty()) {
throw new RuntimeException("数组为空,无法拿到数据!");
}
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
// 拿出头数据
public int gethead(){
if(isEmpty()) {
throw new RuntimeException("数组为空,无法拿到数据!");
}
return arr[front];
}
整个程序的测试代码:
import java.util.Scanner;
public class CirArrayQueue {
public static void main(String[] args) {
ArrayQueue2 arrayQueue = new ArrayQueue2(4);
char key = ' '; // 接收用户输入
Scanner scanner = 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):显示队列头数据");
key = scanner.next().charAt(0);
switch (key) {
case 's': {
arrayQueue.show();
break;
}
case 'a': {
int value = scanner.nextInt();
arrayQueue.addQueue(value);
break;
}
case 'g': {
try {
int queue = arrayQueue.getQueue();
System.out.println("取出的数据是[" + queue + "]");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
}
break;
}
case 'h': {
try {
int firstQueue = arrayQueue.gethead();
System.out.println("取出的头数据是[" + firstQueue + "]");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
}
break;
}
case 'e': {
scanner.close();
loop = false;
break;
}
default:
throw new IllegalArgumentException("Unexpected value: " + key);
}
}
System.out.println("程序退出");
}
}
class ArrayQueue2{
private Integer maxSize; // 队列的最大数量
private Integer front; // 队列的头
private Integer rear; // 队列的尾
private int[] arr; // 定义数组用于存放数据
public ArrayQueue2(Integer maxSize) {
this.maxSize = maxSize; // 给最大值赋值
arr = new int[this.maxSize]; // 初始化数组
front = 0;
rear = 0; // 循环指针都为零
}
public boolean isFull() {
return (rear + 1)%maxSize == front; // 判断是否满了
}
public boolean isEmpty() {
return rear == front; // 判断是否为空(指针无移动)
}
// 添加数据
public void addQueue(Integer data){
if(isFull()) {
System.out.println("队列已满,无法添加数据!");;
return;
}
arr[rear] = data;
rear = (rear + 1) % maxSize;
}
// 拿出数据
public int getQueue(){
if(isEmpty()) {
throw new RuntimeException("数组为空,无法拿到数据!");
}
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
// 拿出头数据
public int gethead(){
if(isEmpty()) {
throw new RuntimeException("数组为空,无法拿到数据!");
}
return arr[front];
}
// 展示所有数据
public void show() {
if(isEmpty()) {
System.out.println("队列为空,无法编列");
return;
}
for(int i = 0; i < (rear + maxSize - front) % maxSize; i++) {
System.out.println("arr["+ (front + i) +"]=" + arr[front + i]);
}
}
}