Circular Queue Visualizer
What is a Circular Queue?
A Circular Queue is an advanced version of a linear queue that connects the end of the queue back to the front, forming a circle. This efficient structure prevents memory wastage and allows better utilization of fixed-size buffers.
Key Characteristics
- Fixed capacity: Size is predetermined at creation
- Two pointers:
- Front: Points to the first element
- Rear: Points to the last element
- Circular behavior: When pointers reach the end, they wrap around to the start
- Efficient space utilization: Reuses empty spaces created after dequeues
Visual Example (Size=5)
- enqueue(10): [10, _, _, _, _] (F=0, R=0)
- enqueue(20): [10, 20, _, _, _] (F=0, R=1)
- enqueue(30): [10, 20, 30, _, _] (F=0, R=2)
- dequeue(): Returns 10 → [_, 20, 30, _, _] (F=1, R=2)
- enqueue(40): [_, 20, 30, 40, _] (F=1, R=3)
- enqueue(50): [_, 20, 30, 40, 50] (F=1, R=4)
- enqueue(60): [60, 20, 30, 40, 50] (F=1, R=0) ← Wraps around!
Implementation Details
- Pointer Movement:
- front = (front + 1) % capacity
- rear = (rear + 1) % capacity
- Full/Empty Conditions:
- Full: (rear + 1) % capacity == front
- Empty: front == rear
- Always one empty slot: Needed to distinguish between full and empty states
Time Complexity
- enqueue(): O(1)
- dequeue(): O(1)
- peekFront(): O(1)
- peekRear(): O(1)
- isEmpty(): O(1)
- isFull(): O(1)
Applications
- CPU Scheduling: Round-robin scheduling algorithms
- Memory Management: Circular buffers in memory systems
- Traffic Systems: Controlling the flow of traffic signals
- Data Streams: Handling continuous data streams (audio/video buffers)
- Producer-Consumer Problems: Where producers and consumers operate at different rates
Advantages Over Linear Queue
- Better memory utilization: Reuses empty spaces
- Efficient operations: No need to shift elements
- Fixed memory footprint: Predictable memory usage
- Real-time systems friendly: Bounded execution time
The circular queue is an essential data structure for systems requiring efficient, fixed-size buffers with constant-time operations. Its circular nature solves the memory wastage problem of linear queues while maintaining simple and predictable performance characteristics, making it ideal for low-level system programming and real-time applications.
Visualize Circular Queue Operations
Circular Queue Implementation
// Circular Queue Implementation (JavaScript)
class CircularQueue {
constructor(capacity) {
this.queue = new Array(capacity);
this.capacity = capacity;
this.front = -1;
this.rear = -1;
this.size = 0;
}
// Check if queue is full
isFull() {
return this.size === this.capacity;
}
// Check if queue is empty
isEmpty() {
return this.size === 0;
}
// Add element to the queue
enqueue(item) {
if (this.isFull()) {
console.log("Queue is full");
return false;
}
if (this.isEmpty()) {
this.front = 0;
}
this.rear = (this.rear + 1) % this.capacity;
this.queue[this.rear] = item;
this.size++;
return true;
}
// Remove element from the queue
dequeue() {
if (this.isEmpty()) {
console.log("Queue is empty");
return null;
}
const item = this.queue[this.front];
this.queue[this.front] = null;
if (this.front === this.rear) {
this.front = -1;
this.rear = -1;
} else {
this.front = (this.front + 1) % this.capacity;
}
this.size--;
return item;
}
// Get front element without removing it
peek() {
if (this.isEmpty()) {
console.log("Queue is empty");
return null;
}
return this.queue[this.front];
}
// Print queue contents
print() {
if (this.isEmpty()) {
console.log("Queue is empty");
return;
}
let i = this.front;
let output = [];
while (true) {
output.push(this.queue[i]);
if (i === this.rear) break;
i = (i + 1) % this.capacity;
}
console.log("Queue contents:", output.join(' -> '));
console.log("Front index:", this.front, "Rear index:", this.rear);
}
}
// Usage
const queue = new CircularQueue(5);
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
queue.enqueue(40);
queue.enqueue(50);
queue.print(); // 10 -> 20 -> 30 -> 40 -> 50
console.log("Dequeued:", queue.dequeue()); // 10
queue.enqueue(60);
queue.print(); // 20 -> 30 -> 40 -> 50 -> 60
console.log("Front element:", queue.peek()); // 20
Features: Enqueue, Dequeue, Peek, isEmpty, isFull, and Print operations
Note: Circular queue efficiently reuses empty spaces created after dequeuing