Deque (Double-Ended Queue)Loading saved progress…

Deque (Double-Ended Queue)

A deque (pronounced deck, short for double-ended queue) is a linear collection that lets you add and remove items at both ends — the front and the back — each in constant time. That makes it a superset of two simpler structures: restrict it to one end and it behaves like a stack, add at one end and remove from the other and it behaves like a queue. Your deque() factory returns an object with eight methods that push, pop, and peek at each end, plus size and isEmpty. See double-ended queue for background.

Signature

function deque(): {
  pushFront(value: unknown): void;   // add value at the front
  pushBack(value: unknown): void;    // add value at the back
  popFront(): unknown | undefined;   // remove + return the front, or undefined if empty
  popBack(): unknown | undefined;    // remove + return the back, or undefined if empty
  peekFront(): unknown | undefined;  // read the front without removing, or undefined
  peekBack(): unknown | undefined;   // read the back without removing, or undefined
  size(): number;                    // how many items are in the deque
  isEmpty(): boolean;                // true when the deque holds nothing
};

Examples

const d = deque();
d.pushBack('a');
d.pushBack('b');
d.pushBack('c');
d.popFront(); // 'a' — oldest out first, like a queue
d.popFront(); // 'b'
const d = deque();
d.pushFront(1);
d.pushFront(2);
d.pushFront(3); // front-to-back: [3, 2, 1]
d.peekFront();  // 3
d.popFront();   // 3 — newest out first, like a stack
const d = deque();
d.pushBack(1);
d.pushFront(0);
d.pushBack(2); // front-to-back: [0, 1, 2]
d.peekFront(); // 0
d.peekBack();  // 2
d.popBack();   // 2
d.size();      // 2

Notes

  • O(1) at both ends — every push, pop, and peek must run in constant time no matter how many items are stored. A doubly linked list gives you this; a plain array does not, because shifting the front is O(n).
  • Empty reads return undefinedpopFront, popBack, peekFront, and peekBack on an empty deque must not throw. Returning undefined is the spec.
  • Any value is valid — including undefined, null, 0, and false. Don't filter or coerce; use size() or isEmpty() to tell an empty deque from a stored undefined.
  • It generalizes a stack and a queue — operate on one end only and it is a stack (last-in, first-out); add at one end and remove from the other and it is a queue (first-in, first-out).
  • Each instance is independent — calling deque() twice gives you two separate deques; one's pushes don't appear in the other.

FAQ

Why back a deque with a doubly linked list instead of an array?
An array makes one end slow: push and pop at the back are O(1), but unshift and shift at the front are O(n) because every element has to be reindexed. A doubly linked list makes all four end operations O(1), since inserting or removing at the head or tail only relinks a couple of pointers and never touches the other nodes.
How does a deque relate to a stack and a queue?
A deque is a superset of both. Use a single end (pushBack and popBack, say) and it behaves like a stack — last-in, first-out. Push at one end and pop at the other and it behaves like a queue — first-in, first-out. Because it can add and remove at either end, it can play either role.
What do pop and peek return on an empty deque?
They return undefined and never throw. Because a stored undefined also reads back as undefined, check size() or isEmpty() first when you need to tell a genuinely empty deque apart from a deque whose end value happens to be undefined.
Loading editor…