例题描述
设计你的循环队列实现。
循环队列是一种线性数据结构,其操作表现基于 FIFO
(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是:可以利用这个队列之前用过的空间。
在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即便在队列前面仍有空间。
但是使用循环队列,我们能使用这些空间去存储新的值。
你的实现应该支持如下操作:
MyCircularQueue(k)
: 构造器,设置队列长度为 k 。
Front
: 从队首获取元素。如果队列为空,返回 -1 。
Rear
: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value)
: 向循环队列插入一个元素。如果成功插入则返回真。
deQueue()
: 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty()
: 检查循环队列是否为空。
isFull()
: 检查循环队列是否已满。
示例:
MyCircularQueue circularQueue = new MycircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1); // 返回 true
circularQueue.enQueue(2); // 返回 true
circularQueue.enQueue(3); // 返回 true
circularQueue.enQueue(4); // 返回 false,队列已满
circularQueue.Rear(); // 返回 3
circularQueue.isFull(); // 返回 true
circularQueue.deQueue(); // 返回 true
circularQueue.enQueue(4); // 返回 true
circularQueue.Rear(); // 返回 4
提示:
- 所有的值都在
0 至 1000
的范围内; - 操作数将在
1 至 1000
的范围内; - 请不要使用内置的队列库。
解题思路
- 队列中通过下标
front
与rear
完成队列范围管理,前者是循环队列的队首元素的下标,后者是循环队列的队尾元素下标。 - 通过顺序表完成队列元素管理,元素通常通过尾插操作进入队列。
代码实现
class MyCircularQueue {
public:
int size;
int capacity;
int *array;
int front;
int rear;
//1. 构造器:构造一个循环队列,元素个数为 k
MyCircularQueue(int k) {
array = (int*)malloc(sizeof(int) * k);
size = 0;
capacity = k;
front = 0;
rear = 0;
}
//2. 入队:插入队列元素
bool enQueue(int value) {
if(size >= capacity){
return false; //队列已满,返回 false
}
array[rear] = value;
rear = (rear + 1) % capacity; //处理下标越界问题
size++;
return true;
}
//3. 出队:将队首元素进行出队操作
bool deQueue() {
if(size <= 0){
return false;
}
size--;
front = (front + 1) % capacity; //处理下标越界问题
return true;
}
//4. 获取队首元素值
int Front() {
if(size <= 0){
return -1;
}
return array[front];
}
//4. 获取队尾元素值
int Rear() {
if(size <= 0) {
return -1;
}
int index = (rear - 1 + capacity) % capacity;
//通过这样取模操作,可以找到rear下标的前一个,即队尾元素下标。
return array[index];
}
//5. 判断队列是否为空
bool isEmpty() {
return size == 0;
}
//6. 判断队列是否已满
bool isFull() {
return size == capacity;
}
};