最近由于忙其他事情,有一段时间没有接触一些基础的数据结构了,前两天遇到一个手写环形队列的题,都搞忘了,再次特地写一篇博客,记录一下,加深印象。
环形队列主要是有几个公式容易忘记,其实理解了也很简单。
几个必要的变量说明
int[] arr:存储队列的数组,也可以用链表做,这里不多赘述
int maxSize:数组的长度,也是队列的最大长度,通常是初始化队列时传入
int front:队头指针,记录数组中队列的队头下标
int size:当前的队列的长度
注:以前学习数据结构时,一般老师或者教材在实现队列都是用的front和rear双指针来表示队头队尾,但其实一个环形队列,我们只需要一个头指针即可。
下面的poll、peek这些命名我是参考的Java中Queue队列操作
公式1:offer入队操作,向队尾添加元素时,需要计算出队列长度,将新的元素添加到队尾
index = (front + size) % maxSize;
扫描二维码关注公众号,回复: 12427821 查看本文章![]()
公式2:poll出队操作,取出队头元素时,front需要向数组后面移动一位
front = (front + 1) % maxSize;
公式3:getLast获取队尾元素操作,该操作一般队列不提供,但这里顺便提一下
last = (front + size - 1) % maxSize;
其实公式1看懂了,公式3很容易理解,就是在队尾的后一个元素插入元素嘛
下面直接上代码
/**
* 数组实现环形队列
*/
public class LoopArrayQueue {
private int[] arr; // 该数据用于存放数据, 模拟队列
private int maxSize; // 表示数组的最大容量
private int front; // 队列头,指向队列的第一个元素
private int size;//记录当前数组中队列的长度
// 创建队列的构造器
public LoopArrayQueue(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
front = 0;
size = 0;
}
// 判断队列是否满
public boolean isFull() {
return size == maxSize;//数组长度和队列长度相同说明队列已满
}
// 判断队列是否为空
public boolean isEmpty() {
return size == 0;
}
// 添加数据到队列,入队列
public void offer(int n) {
// 判断队列是否满
if (isFull()) throw new RuntimeException("队列满,不能加入数据~");
int index = (front + size) % maxSize;//计算出要存放的位置,相当于rear
arr[index] = n;
size++;//队列长度+1
}
// 获取队列的头数据,同时删除数据
public int poll() {
if (isEmpty()) throw new RuntimeException("队列空,不能取数据");
int res = arr[front];
front = (front + 1) % maxSize; //队头的位置向后移动
size--;//队列长度-1
return res;
}
// 读取队列的头数据, 不删除数据
public int peek() {
if (isEmpty()) throw new RuntimeException("队列空的,没有数据~~");
return arr[front];//front起始就指向数组开始
}
/**
* 读取队尾元素 - 一般队列不提供这个个操作
* 只要知道队头位置、数组长度、队列个数就可以用下面的公式求出队尾位置
* tailIndex = (headIndex + count −1) % capacity
* 得到队尾位置后,即可对整个环形队列进行操作。
*/
public int getLast(){
if(isEmpty()) throw new RuntimeException("队列空的,没有数据~~");
int tail = (front + size - 1) % maxSize;
return arr[tail];
}
// 显示队列的所有数据
public void display() {
if (isEmpty())
throw new RuntimeException("队列空的,没有数据~~");
//遍历应该从front开始遍历,遍历次数为队列有效个数
System.out.print("当前队伍:");
for (int i = front; i < front+size; i++) {
System.out.print(arr[i]+"\t");
}
System.out.println("");
}
}
下面进行测试一下:
public static void main(String[] args) {
LoopArrayQueue queue = new LoopArrayQueue(3);//传入队列的长度,这里长度是传入的数值-1
queue.offer(11);
queue.offer(22);
queue.offer(33);
System.out.println("显示队头:"+queue.peek());
System.out.println("显示队尾:"+queue.getLast());
System.out.println("队头出队:"+queue.poll());
System.out.println("队头出队:"+queue.poll());
queue.display();
System.out.println("显示队头:"+queue.peek());
}
运行结果如下图