设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 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 的范围内;
请不要使用内置的队列库。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/design-circular-queue
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
使用动态数组以便在运行阶段创建需要大小的数组
循环队列的实现关键在于isFull()和isEmpty()的实现
设当front = rear = -1时队列为空
当(rear + 1) % capacity = front时队列为满
入队时先后判断满或空否,若为首个元素,则front = rear = 0;否则rear = (rear + 1) % capacity
出队时判断空否,空则front = rear = -1,否则front = (front + 1) % capacity
- class MyCircularQueue {
- private:
- int *data;
- int front, rear;
- int len;
- public:
- MyCircularQueue(int k) {
- data = new int[k];
- front = rear = -1;
- len = k;
- }
-
- ~MyCircularQueue() {
- delete[] data;
- }
-
- bool enQueue(int value) {
- if (isFull())
- return false;
- if (isEmpty())
- front++;
- rear = (rear + 1) % len;//rear后移一位,若到最后则转到数组头部
- data[rear] = value;
- return true;
- }
-
- bool deQueue() {
- if (isEmpty())
- return false;
- if (front == rear && front != -1)//只剩一位
- front = rear = -1;
- else
- front = (front + 1) % len;
- return true;
- }
-
- int Front() {
- if (isEmpty())
- return -1;
- return data[front];
- }
-
- int Rear() {
- if (isEmpty())
- return -1;
- return data[rear];
- }
-
- bool isEmpty() {
- return (front == rear && front == -1);
- }
-
- bool isFull() {
- return ((rear + 1) % len == front);
- }
- };
-
- /**
- * Your MyCircularQueue object will be instantiated and called as such:
- * MyCircularQueue* obj = new MyCircularQueue(k);
- * bool param_1 = obj->enQueue(value);
- * bool param_2 = obj->deQueue();
- * int param_3 = obj->Front();
- * int param_4 = obj->Rear();
- * bool param_5 = obj->isEmpty();
- * bool param_6 = obj->isFull();
- */