定义:把队列的头尾相连接的的顺序存储结构称为循环队列;循环队列的是由顺序表实现的。
为什么要使用循环队列?
循环队列是由顺序表实现,也就是数组;我们还知道队列是尾进头出的,如果让数组头出,那么我们需要将后面的元素依次向前挪动,时间复杂度就高了。这是,我们的前辈就想到了循环数组,让数组头尾相连,这样就不用考虑挪动元素了。
函数介绍及模拟实现
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; }