Skip to content

Queue Visualizer

1/1

What is a queue?

A queue is a linear data structure that follows FIFO — first in, first out. Elements join at the rear (enqueue) and leave from the front (dequeue), like people waiting in line, and both operations take O(1) time. This page animates the simple array version, including the wasted-space flaw that the circular queue fixes.

How it works

  1. Keep an array A of fixed capacity and two indices: front = 0 (the first element) and rear = -1 (the last element). The queue is empty when front > rear.
  2. enqueue(x): if rear == capacity - 1 there is no room at the end. Otherwise increment rear and write A[rear] = x.
  3. dequeue(): if front > rear the queue is empty (underflow). Otherwise read x = A[front], increment front and return x.
  4. peek() returns A[front] without moving anything, and the size is rear - front + 1.

Worked example: enqueue 10, enqueue 20, dequeue, enqueue 30

Capacity 6, starting empty (front = 0, rear = -1):

  • enqueue(10): rear becomes 0 and A[0] = 10. Queue: [10].
  • enqueue(20): rear becomes 1 and A[1] = 20. Queue: [10, 20].
  • dequeue(): returns 10, because it arrived first; front becomes 1. Queue: [20].
  • enqueue(30): rear becomes 2 and A[2] = 30. Queue: [20, 30] with front = 1, rear = 2.

Slot 0 is now behind front. In this simple design neither index ever moves left again, so that slot can never be used again.

The wasted-space problem

Both indices only move right. After enough operations rear reaches the last index and enqueue reports *full* — even if dequeues have emptied most of the array. With capacity 6, enqueue six values and dequeue three: three elements remain and three slots are free, but rear == 5, so the next enqueue is refused.

There are three standard fixes:

  • Compact: when you run out of room, shift the remaining elements back to index 0. Correct, but O(n).
  • Circular queue: wrap the indices with (i + 1) % capacity so freed slots at the start are reused. O(1), nothing shifts.
  • Linked list: keep head and tail pointers; enqueue appends at the tail and dequeue removes the head. O(1) and unbounded.

The visualizer's *Wasted space* button reproduces the problem, *Compact* shows the O(n) fix, and the Circular tab shows the O(1) one.

Queues in standard libraries

  • Python: collections.deque with append and popleft, both O(1); queue.Queue adds locking for threads. Avoid list.pop(0), which is O(n).
  • Java: the Queue interface backed by ArrayDeque or LinkedList. offer, poll and peek return false or null on failure, while add, remove and element throw exceptions.
  • C++: std::queue with push, pop, front and back, an adapter over std::deque by default. pop() returns nothing, so read front() first.
  • JavaScript: array.shift() is O(n); for large queues keep a head index into the array or use a ring buffer.

Where queues are used

  • Breadth-first search and level-order traversal of trees visit nodes in the order they were discovered.
  • Scheduling: CPU ready queues, round-robin time slicing, print spoolers and support-ticket lines.
  • Buffering between a fast producer and a slow consumer: keyboard input, network packets, video frames and message brokers.
  • Rate limiting and caches: a FIFO of timestamps or keys where the oldest entry is evicted first.

There are several kinds of queue. The simple (linear) queue on this page, the circular queue that reuses space, the deque that works at both ends, and the priority queue, which removes the highest-priority element instead of the oldest — usually a binary heap, so it is not FIFO at all.

Common mistakes and interview questions

  • Testing emptiness with front == rear in this design: a queue with one element also has front == rear. Empty is front > rear.
  • Forgetting that a linear array queue can refuse an enqueue while it still has free slots.
  • Computing the size as rear - front instead of rear - front + 1.
  • Using list.pop(0) or array.shift() inside a loop and turning an O(n) algorithm into O(n²).

Popular interview tasks: implement a queue with two stacks, implement a stack with queues, design a circular queue (LeetCode 622), shortest path in a grid or "rotting oranges" with BFS, and the first non-repeating character in a stream.

Time and space complexity

CaseTimeSpaceWhy
enqueueO(1)O(1)Writes one slot after rear.
dequeueO(1)O(1)Moves front one step; nothing shifts.
peek / size / isEmptyO(1)O(1)Index arithmetic only.
compactO(n)O(1)Moves every remaining element back to index 0.
dequeue via list.pop(0)O(n)O(1)Each remaining element shifts one place left.

Queue in Python

class Queue:
    """FIFO queue in a plain array: both indices only move right."""

    def __init__(self, capacity):
        self.A = [None] * capacity
        self.capacity = capacity
        self.front = 0   # first element
        self.rear = -1   # last element; empty when front > rear

    def enqueue(self, x):
        if self.rear == self.capacity - 1:
            raise IndexError("Queue full")  # even if front > 0!
        self.rear = self.rear + 1
        self.A[self.rear] = x

    def dequeue(self):
        if self.front > self.rear:
            raise IndexError("Queue empty")
        x = self.A[self.front]
        self.front = self.front + 1  # this slot is lost for good
        return x

    def peek(self):
        if self.front > self.rear:
            raise IndexError("Queue empty")
        return self.A[self.front]

    def compact(self):
        """Fix #1 for wasted space: shift everything back to index 0, O(n)."""
        n = self.rear - self.front + 1
        for i in range(n):
            self.A[i] = self.A[self.front + i]
        self.front = 0
        self.rear = n - 1

    def clear(self):
        self.front = 0
        self.rear = -1

    def is_empty(self):
        return self.front > self.rear

    def size(self):
        return self.rear - self.front + 1


# q = Queue(6); q.enqueue(10); q.enqueue(20); q.dequeue()  -> 10

The visualizer above shows the same code in Python, C++, Java and JavaScript.

Frequently asked questions

Is a queue FIFO or LIFO?

A queue is FIFO: the element that has waited longest leaves first. LIFO describes a stack.

What is the difference between enqueue and dequeue?

Enqueue adds an element at the rear of the queue; dequeue removes and returns the element at the front. Both are O(1).

Why does a linear array queue say it is full when it has empty slots?

Because front and rear only move right, slots before front are never revisited. A circular queue wraps the indices around so those slots are reused.

Why is list.pop(0) slow in Python?

Removing the first element shifts every remaining element one place left, which is O(n). collections.deque.popleft() is O(1).

Is a priority queue a queue?

Only by name: it removes the element with the highest priority rather than the oldest one, so it is not FIFO. It is usually a binary heap with O(log n) insert and remove.

What are queue overflow and underflow?

Overflow is enqueuing into a full queue; underflow is dequeuing from an empty one. Check isFull() or isEmpty() first, or use a structure that grows.

Keep learning

Last updated