目录
定义:把队列的头尾相连接的的顺序存储结构称为循环队列;循环队列的是由顺序表实现的。
为什么要使用循环队列?
循环队列是由顺序表实现,也就是数组;我们还知道队列是尾进头出的,如果让数组头出,那么我们需要将后面的元素依次向前挪动,时间复杂度就高了。这是,我们的前辈就想到了循环数组,让数组头尾相连,这样就不用考虑挪动元素了。
函数介绍及模拟实现
MyCircularQueue(k)
: 构造器,设置队列长度为 k 。Front
: 从队首获取元素。如果队列为空,返回 -1 。Rear
: 获取队尾元素。如果队列为空,返回 -1 。enQueue(value)
: 向循环队列插入一个元素。如果成功插入则返回真。deQueue()
: 从循环队列中删除一个元素。如果成功删除则返回真。isEmpty()
: 检查循环队列是否为空。isFull()
: 检查循环队列是否已满。
Front()函数
作用:从队首获取元素。
实现原理:先判断队列是否为空,不是空就返回front下标的元素,否则返回-1。
public int Front() {
if(isEmpty()){
return -1;
}
return elem[front];
}
Rear()函数
作用:获取队尾元素。
实现原理:因为是循环队列,所以队尾比较难判断。我们分两种情况,因为我们判断循环队列是否满,运用的是牺牲一个空间来判断,因此,当rear的值是0时,正好他在数组开头,我们所需的值就是,数组最后一个下标的值,我们只需让数组长度减一;若不是数组头,我们仅让rear减一即可。
public int Rear() {
if(isEmpty()){
return -1;
}
int index=(rear==0)?(elem.length-1):(rear-1);
return elem[index];
}
enQueue()函数
作用:向循环队列插入一个元素。如果成功插入则返回真。
实现原理:判断队列是否满,满的话,就插不了,直接返回false;若不空,将rear下标的数数组值改成value,这里rear不能直接加一,因为rear如果一直加,就会超出数组的长度,导致数组下标越界异常,我们需要对其进行操作,让rear加一,再模上数组长度,就不会超过数组的下标范围了。
public boolean enQueue(int value) {
if(isFull()){
return false;
}
elem[rear]=value;
rear=(rear+1)%elem.length;
return true;
}
deQueue()函数
作用:从循环队列中删除一个元素。如果成功删除则返回真。
实现原理:同
enQueue()函数
函数相似
public boolean deQueue() {
if(isEmpty()){
return false;
}
front=(front+1)%elem.length;
return true;
}
isEmpty()函数
作用:检查循环队列是否为空
实现原理:若头尾相等就是空
public boolean isEmpty() {
return front==rear;
}
isFull()函数
作用:检查循环队列是否为满
实现原理:这里体现了对牺牲一个空间来判断是否满;我们让rear向前走一步,如果rear模上数组长度,等于front,那就是满了。
public boolean isFull() {
if(front==(rear+1)%elem.length) {
return true;
}
return false;
}
循环队列模拟题
循环队列例题https://leetcode.cn/problems/design-circular-queue/description/