100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What is a Circular Queue?

Understand circular queues with a Python ring buffer implementation, wraparound logic, and common interview mistakes.

easyQ21 of 227 in Data Structures & Algorithms Est. time: 5 minsLast updated:
Open Code Lab

Expected Interview Answer

A circular queue is a fixed-size queue implemented on an array where the last position wraps around to connect back to the first, allowing enqueue and dequeue operations to reuse freed slots without shifting elements or wasting space.

A regular array-based queue wastes space over time because dequeuing from the front leaves unused slots that are never reclaimed unless elements are shifted, which is O(n). A circular queue solves this by tracking a front and rear index that wrap using modulo arithmetic, so freed slots at the front are reused as new elements are enqueued at the rear. This keeps every enqueue and dequeue operation O(1) while using a fixed amount of memory. Circular queues are the standard structure behind ring buffers used in streaming data, CPU scheduling, and producer-consumer pipelines.

  • O(1) enqueue and dequeue with no element shifting
  • Fixed memory footprint, ideal for buffers
  • Reuses freed slots automatically via wraparound
  • Basis for ring buffers in streaming and I/O systems

AI Mentor Explanation

A stadium’s circular running track used for warm-up laps lets one athlete finish a lap and immediately start the next, wrapping from the final marker straight back to the first — no space is ever wasted like it would be on a straight track that ends. A circular queue works the same way: when the rear index reaches the end of the array, it wraps back to index zero instead of running out of room, reusing slots the front pointer has already vacated.

Step-by-Step Explanation

  1. Step 1

    Allocate a fixed-size array

    Reserve capacity N upfront along with front and rear index variables, both typically starting at -1 or 0.

  2. Step 2

    Enqueue with wraparound

    Insert at rear = (rear + 1) % N, and check for the full condition before inserting.

  3. Step 3

    Dequeue with wraparound

    Remove from front, then advance front = (front + 1) % N.

  4. Step 4

    Track full vs empty

    Use a size counter or sacrifice one slot to distinguish the full state from the empty state, since both can look like front == rear.

What Interviewer Expects

  • Explaining why a plain array-based queue wastes space without wraparound
  • Correctly using modulo arithmetic for the wraparound index
  • Handling the full-vs-empty ambiguity when front equals rear
  • Naming real-world uses such as ring buffers and CPU scheduling

Common Mistakes

  • Forgetting the modulo operation, causing an index-out-of-bounds error
  • Not distinguishing between an empty queue and a full queue when front equals rear
  • Shifting elements on dequeue instead of just moving the front pointer
  • Assuming a circular queue can grow dynamically like a regular list

Best Answer (HR Friendly)

A circular queue is a fixed-size queue where the end wraps back around to the beginning, so instead of wasting the space left behind by items that have been removed, new items can reuse it. It is the data structure behind ring buffers, which show up anywhere you need to process a continuous stream of data with a fixed amount of memory, like audio buffers or task schedulers.

Code Example

Fixed-size circular queue
class CircularQueue:
    def __init__(self, capacity):
        self.data = [None] * capacity
        self.capacity = capacity
        self.front = 0
        self.size = 0

    def enqueue(self, value):
        if self.size == self.capacity:
            raise OverflowError("Queue is full")
        rear = (self.front + self.size) % self.capacity
        self.data[rear] = value
        self.size += 1

    def dequeue(self):
        if self.size == 0:
            raise IndexError("Queue is empty")
        value = self.data[self.front]
        self.front = (self.front + 1) % self.capacity
        self.size -= 1
        return value

Follow-up Questions

  • How does a circular queue differ from a standard array-based queue?
  • How would you distinguish a full circular queue from an empty one?
  • What real-world systems use ring buffers based on circular queues?
  • How would you implement a circular queue using a fixed-size list instead of tracking a separate size counter?

MCQ Practice

1. What operation lets a circular queue wrap its index back to the start of the array?

Taking the index modulo the array capacity produces the wraparound behavior.

2. What problem does a circular queue solve compared to a naive array-based queue?

Without wraparound, dequeued slots at the front are never reused, wasting array space over time.

3. What is the time complexity of enqueue and dequeue in a circular queue?

Both operations only update index pointers and a size counter, no shifting required.

Flash Cards

Circular queueA fixed-size array-based queue where the rear index wraps back to the start, reusing freed slots.

Wraparound formula(index + 1) % capacity — advances an index and loops it back to zero at the boundary.

Full vs empty ambiguityfront == rear can mean either empty or full; resolved with a size counter or by sacrificing one slot.

Real-world useRing buffers for streaming data, audio buffers, and CPU task scheduling.

1 / 4

Continue Learning