Implement Queue using Arrays
Build a queue — enqueue, dequeue, front, size — on a fixed array.
Intuition
Two pointers, front and rear, both only move forward — so wrap them around with modulo and the array becomes a ring. No element ever shifts; the circle just rotates under the indices.
A circular buffer. The insight is that front and rear should wrap with modulo instead of shifting elements — that's what keeps dequeue O(1). Tracking count rather than comparing the two indices is the detail that removes the classic full-versus-empty ambiguity, since both states otherwise look identical.
Approach
Naive front-removal is O(n)
Dequeuing from a[0] and shifting everything left wastes the whole array walk. The fix: move the pointer, not the data.
Circular indexing
rear = (rear + 1) % cap on enqueue, front = (front + 1) % cap on dequeue. A separate count distinguishes full from empty (both have front == rear otherwise).
All O(1)
Every operation is one read/write plus modular arithmetic.
Solution & live demo
Common pitfalls
Shifting the array on dequeue
v = self.a[0] self.a = self.a[1:] return v
v = self.a[self.front] self.front = (self.front + 1) % len(self.a)
Shifting is O(n) per dequeue and defeats the point of the structure. Moving the front index instead leaves the data where it is — nothing is copied.
Distinguishing full from empty by comparing indices
if self.front == self.rear: # empty?
if self.count == len(self.a): raise OverflowError
if self.count == 0: raise IndexError("empty")In a circular buffer front == rear is true both when it's completely empty and when it's completely full — the indices alone can't tell them apart. An explicit count resolves it without sacrificing a slot.
Computing the rear without wrapping
rear = self.front + self.count
rear = (self.front + self.count) % len(self.a)
Once front has advanced, the write position runs past the end of the array and raises an index error, even though there is free space at the start. The modulo is what makes the buffer circular.
Edge cases
After cap enqueues the rear index re-enters at 0 — modulo handles it silently.
Track count; front==rear alone can't tell the two apart.