一、环形队列的概念:
1.使用数组模拟队列,空间只能使用一次,不能重复利用。浪费空间。
2.使用环形队列可以重复使用。节省空间
二、循环队列图解:
三、数组模拟环形队列思路:
1.首先front和rear变量初始化不再指向 -1 ;而是指向 0【指向了第一个数据】 ;rear 最终指向的并不是最后一个位置,而是最后一个位置的前一个位置。要预留出来一个作为约定。【所以如果maxSize =4,其实只能存入3个数据】
2.当存入数据时,先保存数据,在变化rear指针。不能简单的将rear++了。因为要考虑环形【当rear指向最后时,在增加一个数据,就从第一个位置开始增加】,所以存入数据时,rear的变化应该是:(rear+1)%maxSize .
3.当输出数据时,先输出在修改front指针。因为front在前面做了调整,指向第一个数据。也需要考虑环形的问题。front的变化:(front+1)%maxSize.
4.判断是否为空和单向队列一样。
5.判断队列是否为满。条件并不是 rear == maxSize-1. 考虑环形的问题:(rear + 1) % maxSize == front ;
6. 获取头部数据。直接将front下标的数据返回,不需要front+1.
7.显示队列数据【front也要取模:(front +1) % maxSize】
四、代码实现
//用数组模拟环形队列
class CricleQueue {
private int front = 0; //输出指针
private int rear = 0; //输入指针
private int maxSize; //队列容量
private int[] array;
public CricleQueue(int maxSize) {
this.maxSize = maxSize;
array = new int[maxSize];
}
//判断是否为空
public boolean isEmpty() {
return front == rear;
}
//判断是否为满
public boolean isFull() {
//★★★★:环形队列考虑 %
return (rear + 1) % maxSize == front;
}
//增加数据
public void add(int data) {
if (isFull()) {
System.out.println("队列已满");
return;
}
array[rear] = data;
//★★★★: 考虑用 %
rear = (rear + 1) % maxSize;
}
//获取数据
public int getData() {
if (isEmpty()) {
System.out.println("队列已空");
return -1;
}
int res = front;
//★★★★ :考虑用 % 【先输出在变化】
front = (front + 1) % maxSize;
return array[res];
}
//显示队列
public void show() {
if (isEmpty()) {
System.out.println("队列为空");
return;
}
while (!isEmpty()) {
System.out.print(array[front] + "\t");
front = (front + 1) % maxSize;
}
}
//获取头部数据
public int getHead() {
return array[front];
}
}