All subjects · Computer Science · WCP04 Advanced Practical Programming and Problem-solving

Implementing a circular queue in a fixed-length list

Edexcel IAL Computer Science · WCP04 Advanced Practical Programming and Problem-solving

A queue is first in, first out (FIFO). A circular queue stores it in a fixed-length list and lets the rear wrap round to the start, so space freed at the front is reused without moving any items.

Practise this in the app: instant marking and a fix for every mistake. Free, no email needed to start.

Practise this lesson

Why circular?

In a simple fixed-length queue, the front pointer moves forward each time an item leaves, so the cells behind it are wasted and the queue soon reports full. Shifting every item forward instead is slow for long queues. A circular queue treats the list as a ring: after the last index comes index 0.

The pointers

The implementation

Enqueue checks for full, moves rear on, then stores the item. Dequeue checks for empty, takes the item at front, then moves front on.

class CircularQueue:
    def __init__(self, capacity):
        self.items = [None] * capacity
        self.capacity = capacity
        self.front = 0
        self.rear = -1
        self.size = 0

    def is_empty(self):
        return self.size == 0

    def is_full(self):
        return self.size == self.capacity

    def enqueue(self, item):
        if self.is_full():
            return False
        self.rear = (self.rear + 1) % self.capacity
        self.items[self.rear] = item
        self.size = self.size + 1
        return True

    def dequeue(self):
        if self.is_empty():
            return None
        item = self.items[self.front]
        self.items[self.front] = None
        self.front = (self.front + 1) % self.capacity
        self.size = self.size - 1
        return item

Watching it wrap

With capacity 4, the fifth enqueue fails. After two dequeues, F goes into index 0: the rear has wrapped round.

# CircularQueue class as above

q = CircularQueue(4)
for job in ["A", "B", "C", "D", "E"]:
    print(job, q.enqueue(job))
print(q.dequeue(), q.dequeue())
q.enqueue("F")
print(q.items, q.front, q.rear, q.size)

Output:

A True
B True
C True
D True
E False
A B
['F', None, 'C', 'D'] 2 0 3

Worked example

A circular queue has capacity 5, front = 3, rear = 1 and size = 4. Where will the next item be stored, and what are front and size after one dequeue?

  1. Next enqueue: rear = (1 + 1) % 5 = 2.
  2. One dequeue: front = (3 + 1) % 5 = 4; size = 4 - 1 = 3.

Answer: The next item goes in index 2; after a dequeue, front = 4 and size = 3.

Key idea: Fixed-length list plus front, rear and size; move a pointer with (p + 1) % capacity; empty when size == 0, full when size == capacity; check before enqueue and dequeue.

Check yourself

  1. The CircularQueue class from the lesson is included in the code below. What does this print? ```python class CircularQueue: def __init__(self, capacity): self.items = [None] * capacity self.capacity = capacity self.front = 0 self.rear = -1 self.size = 0 def is_empty(self): return self.size == 0 def is_full(self): return self.size == self.capacity def enqueue(self, item): if self.is_full(): return False self.rear = (self.rear + 1) % self.capacity self.items[self.rear] = item self.size = self.size + 1 return True def dequeue(self): if self.is_empty(): return None item = self.items[self.front] self.items[self.front] = None self.front = (self.front + 1) % self.capacity self.size = self.size - 1 return item q = CircularQueue(5) for x in range(5): q.enqueue(x) q.dequeue() q.enqueue(9) print(q.rear) ```
    Show answer

    0. Five items fill indexes 0 to 4 (rear = 4). After one dequeue there is space, and rear moves to (4 + 1) % 5 = `0`.

  2. The CircularQueue class from the lesson is included in the code below. What does this print? ```python class CircularQueue: def __init__(self, capacity): self.items = [None] * capacity self.capacity = capacity self.front = 0 self.rear = -1 self.size = 0 def is_empty(self): return self.size == 0 def is_full(self): return self.size == self.capacity def enqueue(self, item): if self.is_full(): return False self.rear = (self.rear + 1) % self.capacity self.items[self.rear] = item self.size = self.size + 1 return True def dequeue(self): if self.is_empty(): return None item = self.items[self.front] self.items[self.front] = None self.front = (self.front + 1) % self.capacity self.size = self.size - 1 return item q = CircularQueue(3) for x in "ABC": q.enqueue(x) for _ in range(3): q.dequeue() q.enqueue("D") print(q.front) ```
    Show answer

    0. Three dequeues move front from 0 to 1, 2, then (2 + 1) % 3 = `0`. D is stored at index 0, which is where front now points.

  3. The CircularQueue class from the lesson is included in the code below. What does this print? ```python class CircularQueue: def __init__(self, capacity): self.items = [None] * capacity self.capacity = capacity self.front = 0 self.rear = -1 self.size = 0 def is_empty(self): return self.size == 0 def is_full(self): return self.size == self.capacity def enqueue(self, item): if self.is_full(): return False self.rear = (self.rear + 1) % self.capacity self.items[self.rear] = item self.size = self.size + 1 return True def dequeue(self): if self.is_empty(): return None item = self.items[self.front] self.items[self.front] = None self.front = (self.front + 1) % self.capacity self.size = self.size - 1 return item q = CircularQueue(2) print(q.enqueue(1), q.enqueue(2), q.enqueue(3), q.is_full()) ```
    Show answer

    True True False True. The first two enqueues succeed; the third finds size == capacity and returns False. Output: `True True False True`

  4. The CircularQueue class from the lesson is included in the code below. What does this print? ```python class CircularQueue: def __init__(self, capacity): self.items = [None] * capacity self.capacity = capacity self.front = 0 self.rear = -1 self.size = 0 def is_empty(self): return self.size == 0 def is_full(self): return self.size == self.capacity def enqueue(self, item): if self.is_full(): return False self.rear = (self.rear + 1) % self.capacity self.items[self.rear] = item self.size = self.size + 1 return True def dequeue(self): if self.is_empty(): return None item = self.items[self.front] self.items[self.front] = None self.front = (self.front + 1) % self.capacity self.size = self.size - 1 return item q = CircularQueue(3) q.enqueue("x") q.enqueue("y") q.dequeue() q.enqueue("z") q.enqueue("w") print(q.dequeue(), q.dequeue(), q.dequeue(), q.dequeue()) ```
    Show answer

    y z w None. FIFO: y, then z, then w leave in the order they joined; the fourth dequeue finds the queue empty and returns None. Output: `y z w None`

  5. A circular queue with capacity 8 has rear = 6. After 3 successful enqueues, what is rear?
    Show answer

    1. rear moves 6 to 7 to 0 to 1: (6 + 3) % 8 = 1.

  6. What is the main advantage of a circular queue over a linear queue in a fixed-length list?
    • It allows items to leave from either end
    • Space freed by dequeued items is reused without shifting the remaining items
    • It sorts items as they are added
    • It never becomes full
    Show answer

    Space freed by dequeued items is reused without shifting the remaining items. The rear pointer wraps to the freed cells at the start of the list.

  7. In an implementation without a size counter, front == (rear + 1) % capacity is true both when the queue is empty and when it is full. Which fix does the lesson's class use?
    • Make the list one item longer each time
    • Reset the front and rear pointers to 0 after every dequeue
    • Store the items in a dictionary
    • Keep a size counter and test size == 0 or size == capacity
    Show answer

    Keep a size counter and test size == 0 or size == capacity. A separate count removes the ambiguity. (Another common fix leaves one cell always unused.)

Practise with instant feedback

Sources

Last updated 8 November 2026. Spotted a mistake? Tell us.