Deque (Double-Ended Queue)

You already know a normal queue. You add at the back. You remove from the front. That is it. One door in, one door out. But what if you need to add at the front too? Or remove from the back? A plain queue cannot do that. This is where a deque helps. It lets you add and remove from both ends.

📚 What Is a Deque?

A deque is a double-ended queue. That means you can add and remove from both ends, the front and the back.

So you get four moves instead of two:

  • pushFront — add an item at the front.
  • pushBack — add an item at the back.
  • popFront — remove an item from the front.
  • popBack — remove an item from the back.

The name is said like “deck”, the same as a deck of cards. Keep that in your head. It helps.

Think of a normal queue as a one-way street. Cars enter from one end. They leave from the other end. A deque is a two-way street. A car can enter or leave from either end. Both ends are fully open.

Note

A deque is the flexible parent of both the stack and the queue. Use only the back? It behaves like a stack. Use the back to add and the front to remove? It behaves like a queue. So a deque can pretend to be either one.

🎯 Why Do We Need It?

Here is the real pain. Say you are tracking the recent items a user touched. The newest one must sit at the front. With a plain queue you can only add at the back. So you are stuck. A deque fixes this. The front is open too.

Let me show you a picture of the two ends:

pushFront / popFront

10

20

30

pushBack / popBack

Both sides can grow. Both sides can shrink. That is the whole idea.

A few common places where a deque is the right tool:

  • Sliding window problems — you keep a window of items moving across an array. Old items leave from one end. New items enter from the other end. A deque does both cheaply.
  • Undo history — you keep the most recent actions. New actions go in at one end. When the history gets too long, you drop the oldest from the other end.
  • A web browser’s back and forward — pages stack on both sides as you move around.

Tip

When you see a problem that says “keep the most recent N things” or “remove from both ends”, you should think of a deque. That hint shows up a lot in coding rounds.

⚙️ How the Four Operations Work

Picture the deque as a row of boxes. Let me walk through each move with a tiny example. We start empty.

  • pushBack(10) → row is 10
  • pushBack(20) → row is 10 20
  • pushFront(5) → row is 5 10 20
  • popFront() → removes 5, row is 10 20
  • popBack() → removes 20, row is 10

See how the front and the back both stay open the whole time? You never have to shift anything around in your head. You just pick the end you want.

Caution

Before you call popFront or popBack, check that the deque is not empty. Popping from an empty deque is a common bug. It either crashes or hands you garbage, depending on the language.

💻 Deque in Five Languages

Good news. You almost never build a deque by hand. Every language ships one ready to use. Here is the same demo in each. It does the four moves and prints the result.

A quick note on C first. The C standard library has no built-in deque. So in C you build your own. You usually use an array (with a front and a rear index) or a doubly linked list. The code below shows a small array-based version so you can see the idea.

Python gives you collections.deque, fast on both ends and very easy to read.

deque_demo.py
from collections import deque
d = deque()
d.append(10) # back: 10
d.append(20) # back: 10 20
d.appendleft(5) # front: 5 10 20
print("Deque:", list(d))
d.popleft() # removes 5
d.pop() # removes 20
print("Deque:", list(d))

The output of the above code will be:

Deque: [5, 10, 20]
Deque: [10]

Output

Every version does the same four moves: two pushes, one push at the front, then a pop from each end. You end with just 10 left. The exact bracket style differs by language, but the deque is identical.

⏱️ How Fast Is It?

This is the best part. A real deque does push and pop at O(1) on both ends. O(1) means the time stays the same no matter how many items are inside. You touch one end. You are done.

Here is the cost of each move:

Operation What It Does Time
pushFront Add an item at the front O(1)
pushBack Add an item at the back O(1)
popFront Remove an item from the front O(1)
popBack Remove an item from the back O(1)

Caution

One catch with the JavaScript array. unshift and shift work at the front, but they shift every other element by one spot. So they are really O(n), not O(1). For small data it is fine. For heavy front work in JS, use a real deque library or a doubly linked list.

⚠️ Common Mistakes

A few slips that trip up beginners. Watch for these.

  • Popping an empty deque. Always check it is not empty first, or you get a crash or junk value.
  • Mixing up the ends. addFirst vs addLast, popleft vs pop. Read the method name slowly. Match it to the end you actually want.
  • Using a JS array and expecting O(1) at the front. shift and unshift are O(n). Know this before you build something big.
  • Reaching for a deque when a plain queue is enough. If you only ever add at one end and remove from the other, a normal queue is simpler. Use a deque when you truly need both ends.

🧩 What You’ve Learned

✅ A deque is a double-ended queue. You can add and remove from both the front and the back.

✅ The four moves are pushFront, pushBack, popFront, and popBack.

✅ It shines in sliding window problems and undo history, anywhere you need both ends open.

✅ Every language ships one: std::deque, ArrayDeque, collections.deque, and a plain array in JS. In C you build your own.

✅ A real deque does push and pop in O(1) at both ends, but a JS array’s front moves are O(n).

Check Your Knowledge

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

  1. 1

    What makes a deque different from a normal queue?

    Why: A deque is double-ended, so both the front and the back are open for adding and removing.

  2. 2

    Which set of operations belongs to a deque?

    Why: A deque supports pushing and popping at both ends, giving four operations.

  3. 3

    What is the time complexity of pushFront and popBack on a proper deque?

    Why: A real deque touches just one end, so both pushes and pops are O(1).

  4. 4

    Why can a JavaScript array's front operations be slow?

    Why: shift and unshift reindex all remaining elements, so front operations are O(n), not O(1).

🚀 What’s Next?

Share & Connect