Queues

Easy

A queue is a First-In-First-Out (FIFO) data structure. Think of a line at a store - first person in line is first served. Queues are essential for BFS, scheduling, buffering, and any scenario where order of arrival matters.

Interactive Visualization

Queue
Frontdequeue / peek
Oldest -> Newest
Backenqueue
#11Front/Back
Output
-
enqueueenqueue(1) - Add 1 to the back of the queue
1 / 9
Key Insight: FIFO (First-In-First-Out): the oldest element leaves first, like a real-world line.

Time Complexity

OperationAverage
EnqueueO(1)
DequeueO(1)*
PeekO(1)
isEmptyO(1)

Key Points

  • FIFO: First In, First Out
  • enqueue: add to back, dequeue: remove from front
  • JS arrays can work as queues but shift() is O(n)
  • For performance, use a proper Queue class or linked list
  • BFS (Breadth-First Search) uses a queue
  • Used for: level-order traversal, scheduling, buffering

Code Examples

Queue Operations (Simple)

// Using array as queue (simple but not optimal)
const queue = []

// Enqueue - add to back - O(1)
queue.push(1)  // [1]
queue.push(2)  // [1, 2]
queue.push(3)  // [1, 2, 3]

// Dequeue - remove from front - O(n)!
queue.shift()  // Returns 1, queue is [2, 3]
queue.shift()  // Returns 2, queue is [3]

// Peek front
queue[0]  // 3

// ⚠️ shift() is O(n) - not ideal for large queues

Arrays work but shift() is slow

Efficient Queue Class

class Queue {
  constructor() {
    this.items = {}
    this.head = 0
    this.tail = 0
  }

  enqueue(item) {
    this.items[this.tail] = item
    this.tail++
  }

  dequeue() {
    if (this.isEmpty()) return undefined
    const item = this.items[this.head]
    delete this.items[this.head]
    this.head++
    return item
  }

  peek() {
    return this.items[this.head]
  }

  isEmpty() {
    return this.tail === this.head
  }

  size() {
    return this.tail - this.head
  }
}

// All operations O(1)!

Object-based queue avoids shifting

BFS Tree Traversal

function levelOrder(root) {
  if (!root) return []

  const result = []
  const queue = [root]

  while (queue.length > 0) {
    const levelSize = queue.length
    const level = []

    for (let i = 0; i < levelSize; i++) {
      const node = queue.shift()
      level.push(node.val)

      if (node.left) queue.push(node.left)
      if (node.right) queue.push(node.right)
    }

    result.push(level)
  }

  return result
}

// Tree:     1
//          / \
//         2   3
// Output: [[1], [2, 3]]

Queue enables level-by-level processing

BFS Shortest Path

function shortestPath(graph, start, end) {
  const queue = [[start, 0]]  // [node, distance]
  const visited = new Set([start])

  while (queue.length > 0) {
    const [node, dist] = queue.shift()

    if (node === end) return dist

    for (const neighbor of graph[node]) {
      if (!visited.has(neighbor)) {
        visited.add(neighbor)
        queue.push([neighbor, dist + 1])
      }
    }
  }

  return -1  // No path found
}

// BFS finds shortest path in unweighted graphs
// because it explores level by level

BFS guarantees shortest path in unweighted graph

Number of Islands (BFS)

function numIslands(grid) {
  let count = 0

  for (let i = 0; i < grid.length; i++) {
    for (let j = 0; j < grid[0].length; j++) {
      if (grid[i][j] === '1') {
        count++
        bfs(grid, i, j)  // Mark entire island
      }
    }
  }

  return count
}

function bfs(grid, r, c) {
  const queue = [[r, c]]
  grid[r][c] = '0'  // Mark visited

  while (queue.length > 0) {
    const [row, col] = queue.shift()
    const dirs = [[1,0], [-1,0], [0,1], [0,-1]]

    for (const [dr, dc] of dirs) {
      const nr = row + dr, nc = col + dc
      if (nr >= 0 && nr < grid.length &&
          nc >= 0 && nc < grid[0].length &&
          grid[nr][nc] === '1') {
        grid[nr][nc] = '0'
        queue.push([nr, nc])
      }
    }
  }
}

BFS explores all connected cells

Stack vs Queue

// STACK (LIFO) - Last In, First Out
// Like a stack of plates
const stack = []
stack.push(1)  // [1]
stack.push(2)  // [1, 2]
stack.pop()    // 2 (last added)

// Use for: DFS, recursion, undo, matching

// QUEUE (FIFO) - First In, First Out
// Like a line at a store
const queue = []
queue.push(1)  // [1]
queue.push(2)  // [1, 2]
queue.shift()  // 1 (first added)

// Use for: BFS, scheduling, buffering

// Easy to remember:
// Stack = DFS = go DEEP first
// Queue = BFS = go WIDE first

Stack for DFS, Queue for BFS

Common Mistakes

  • Using array.shift() in hot path (O(n) each call)
  • Confusing BFS (queue) with DFS (stack)
  • Not tracking visited nodes in graph BFS (infinite loop)
  • Forgetting queue for shortest path problems

Interview Tips

  • BFS = Queue, DFS = Stack (or recursion)
  • BFS finds shortest path in UNWEIGHTED graphs
  • Level-order tree traversal = BFS with a queue
  • For large queues, implement O(1) dequeue

Practice Problems

Related Concepts