Implement Circular queue.
A circular queue is a data structure that uses a fixed-size array or a linked list to represent a queue. In a circular queue, when the end of the queue is reached, it wraps around to the beginning.
- The circular queue has the advantage of efficiently utilizing space and avoiding the need to shift elements when the front of the queue is dequeued.
- A circular queue maintains two pointers:
front
andrear
. front
points to the front (head) of the queue, andrear
points to the rear (tail) of the queue.- Initially, both pointers are set to -1 to indicate an empty queue.
- The
enqueue
operation adds an element to the rear of the queue. - The
dequeue
operation removes an element from the front of the queue.
#include <iostream>
#include <vector>
class CircularQueue {
private:
std::vector<int> array;
int front;
int rear;
int size;
int capacity;
public:
CircularQueue(int capacity) : array(capacity), front(-1), rear(-1), size(0), capacity(capacity) {}
bool isEmpty() const {
return size == 0;
}
bool isFull() const {
return size == capacity;
}
void enqueue(int value) {
if (isFull()) {
std::cout << "Queue is full. Cannot enqueue." << std::endl;
return;
}
if (isEmpty()) {
front = 0;
}
rear = (rear + 1) % capacity;
array[rear] = value;
size++;
std::cout << "Enqueued: " << value << std::endl;
}
void dequeue() {
if (isEmpty()) {
std::cout << "Queue is empty. Cannot dequeue." << std::endl;
return;
}
std::cout << "Dequeued: " << array[front] << std::endl;
if (front == rear) {
// Last element is dequeued, reset front and rear
front = rear = -1;
} else {
front = (front + 1) % capacity;
}
size--;
}
int frontValue() const {
if (isEmpty()) {
std::cerr << "Queue is empty. No front value." << std::endl;
return -1; // Assuming -1 represents an invalid value in this context
}
return array[front];
}
int rearValue() const {
if (isEmpty()) {
std::cerr << "Queue is empty. No rear value." << std::endl;
return -1; // Assuming -1 represents an invalid value in this context
}
return array[rear];
}
};
int main() {
CircularQueue cq(5);
cq.enqueue(1);
cq.enqueue(2);
cq.enqueue(3);
std::cout << "Front: " << cq.frontValue() << ", Rear: " << cq.rearValue() << std::endl;
cq.dequeue();
cq.enqueue(4);
cq.enqueue(5);
cq.enqueue(6); // Trying to enqueue when the queue is full
std::cout << "Front: " << cq.frontValue() << ", Rear: " << cq.rearValue() << std::endl;
cq.dequeue();
cq.dequeue();
cq.dequeue();
cq.dequeue(); // Trying to dequeue when the queue is empty
return 0;
}
Output:
Enqueued: 1
Enqueued: 2
Enqueued: 3
Front: 1, Rear: 3
Dequeued: 1
Enqueued: 4
Enqueued: 5
Enqueued: 6
Front: 2, Rear: 6
Dequeued: 2
Dequeued: 3
Dequeued: 4
Dequeued: 5