Queue Using Array

You know a queue already. It is just a line where people join at the back and leave from the front. The first one in is the first one out. Now the question is, how do we actually build that in code? The simplest way is to use an array. So that is what we will do here. We keep an array and two markers, and we move them as people join and leave.

🎯 The Problem We Are Solving

Say you are writing code for a printer. Print jobs come in one after another. The printer must handle them in order. The first job sent should print first.

You need a place to hold those waiting jobs. And you need to take them out in the same order they arrived. That is exactly a queue. The pain here is order. If you store the jobs but pull them out in the wrong order, someone’s page prints before another person’s page that came in earlier. People get annoyed.

A queue using an array fixes this. You add to one end. You remove from the other end. Order is preserved.

πŸ“š The Two Markers: Front and Rear

To run a queue on an array, we track two positions.

  • front points to the item that will leave next. That is the oldest item still waiting.
  • rear points to the last item we added. That is the newest item.

When someone joins the queue, we move rear forward and write the value there. We call this enqueue, which just means β€œadd to the back.”

When someone leaves, we read the value at front and move front forward. We call this dequeue, which just means β€œremove from the front.”

Here is a small queue holding three jobs.

front

10

20

30

rear

The 10 is the oldest, so it leaves first. The 30 is the newest, so it leaves last.

Note

A queue is FIFO, which means First In, First Out. Compare that with a stack, which is LIFO (Last In, First Out). A queue is fair. Whoever waited longest gets served first.

🧠 Steps to Build an Array Queue

Before any code, let us walk through the plan in plain steps. We will use a fixed-size array. Fixed size means we decide the capacity up front and it does not grow.

We start with the markers set up like this.

  • Set front = 0 and rear = -1. The rear = -1 just means the queue is empty, nothing added yet.
  • Keep a size counter so we always know how many items are inside.

To enqueue (add a value):

  1. First check if the queue is full. If size equals the capacity, stop. There is no room.
  2. Move rear forward by one.
  3. Write the new value at rear.
  4. Increase size by one.

To dequeue (remove a value):

  1. First check if the queue is empty. If size is 0, stop. Nothing to remove.
  2. Read the value at front. That is the value leaving.
  3. Move front forward by one.
  4. Decrease size by one.
  5. Return the value we read.

To peek at the front: just read the value at front without moving anything.

Now let us see it in real code.

πŸ’» Array Queue in Five Languages

This program builds a fixed-capacity queue. It enqueues a few numbers, peeks at the front, then dequeues them one by one. Watch the output. The numbers come out in the same order they went in.

queue_array.py
CAPACITY = 5
# A fixed-size queue using a list
queue = [0] * CAPACITY
front = 0
rear = -1
qsize = 0
# Add a value at the back
def enqueue(value):
global rear, qsize
if qsize == CAPACITY: # queue is full
print(f"Queue is full. Cannot add {value}")
return
rear = rear + 1 # move rear forward
queue[rear] = value # write the value
qsize = qsize + 1
print(f"Enqueued {value}")
# Remove a value from the front
def dequeue():
global front, qsize
if qsize == 0: # queue is empty
print("Queue is empty. Nothing to remove")
return -1
value = queue[front] # read the oldest value
front = front + 1 # move front forward
qsize = qsize - 1
return value
# Look at the front without removing
def peek():
if qsize == 0:
return -1
return queue[front]
enqueue(10)
enqueue(20)
enqueue(30)
print(f"Front is {peek()}")
print(f"Removed {dequeue()}")
print(f"Removed {dequeue()}")
print(f"Front is {peek()}")

The output of the above code will be:

Output
Enqueued 10
Enqueued 20
Enqueued 30
Front is 10
Removed 10
Removed 20
Front is 30

Tip

Notice that both enqueue and dequeue do a fixed amount of work. They just touch one spot in the array and move a marker. They do not loop over the other items. So both run in O(1) time, which means constant time. The size of the queue does not change how long they take.

⚠️ The Wasted Space Problem

This simple version works. But it has a flaw that will bite you later. Look at what happens to front over time.

Every time you dequeue, front moves to the right. It never comes back. So those slots on the left, the ones you already removed, just sit there. They are empty, but you cannot use them again.

Picture a queue with capacity 5. You enqueue 5 items, so rear is at the last slot. Then you dequeue 3 items. Now front is sitting at index 3.

used: gone

used: gone

used: gone

40 front

50 rear

The first three slots are wasted. They are empty. But if you try to enqueue now, your code says the queue is full, because rear has already reached the end. You have free slots but you cannot use them. That is the wasted space problem.

You have two ways to deal with this.

  • One way is to shift everything left each time you dequeue. But shifting all the items is slow. It turns a fast O(1) dequeue into a slow O(n) one. Not good.
  • The better way is to let rear wrap back around to the start when it reaches the end. So when the back of the array is full but the front has empty slots, you reuse those front slots. This idea is called a circular queue.

Caution

The plain array queue is fine for learning, and for cases where you fill it once and drain it once. But for a queue that runs for a long time, with lots of adds and removes, use a circular queue. Otherwise you keep losing space until the queue falsely reports full.

⏱️ Time and Space Complexity

Here is how the array queue performs.

Operation Time Why
enqueue O(1) Move rear and write one slot. No loop.
dequeue O(1) Read front and move it. No loop.
peek (front) O(1) Just read one slot.
Space O(n) The array holds up to n items.

All three operations are constant time. That is the good part. The cost is the wasted space we just talked about.

🧩 What You’ve Learned

  • βœ… A queue is FIFO. The first item in is the first item out. It keeps order.
  • βœ… You build an array queue with two markers, front and rear, plus a size counter.
  • βœ… enqueue moves rear forward and writes the value. dequeue reads front and moves it forward.
  • βœ… enqueue, dequeue, and peek all run in O(1) constant time.
  • βœ… The simple version wastes space because front keeps moving right and never reuses the freed slots.
  • βœ… A circular queue fixes this by wrapping rear back to the start to reuse those empty front slots.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    In a queue, which item leaves first?

    Why: A queue is FIFO, so the oldest item, the one pointed to by front, leaves first.

  2. 2

    What does the enqueue operation do?

    Why: Enqueue adds to the back, so it moves rear forward and writes the value at that spot.

  3. 3

    Why does the simple array queue waste space?

    Why: Dequeue keeps pushing front to the right, so the slots it leaves behind sit empty and unused.

  4. 4

    What is the time complexity of enqueue and dequeue in this array queue?

    Why: Both operations do a fixed amount of work, touching one slot and moving a marker, so they are O(1).

πŸš€ What’s Next?

Share & Connect