Chapter 8: Queues and Deques

Chapter 8: Queues and Deques · Study Questions
The queue ADT and FIFOArray-based queueCircular queueLinked queueDeque and sliding windowApplications
Sercan KÜLCÜ · Giresun University · Computer Engineering

Multiple Choice · The Queue ADT

Question 1: FIFO Order

Starting from an empty queue, we run enqueue(4), enqueue(7), dequeue(), enqueue(1), enqueue(9), dequeue(). What does first() return?

FIFO: the first dequeue removes 4 and the second 7, leaving 1, 9 (front to rear) → first() = 1. Answering 9 is stack (LIFO) thinking: the front holds the oldest item, not the newest.

Multiple Choice · The Queue ADT

Question 2: The Call That Throws

Which call on an empty Queue<Integer> q = new LinkedList<>() throws NoSuchElementException?

add/remove/element throw; offer/poll/peek return special values: on an empty queue poll and peek give null, and offer gives true on success. Many expect peek to throw; the throwing version is element().

Short Answer · The Queue ADT

Question 3: Output of a Java Queue

What does the program print?

Queue<Integer> q = new ArrayDeque<>();
for (int i = 1; i <= 4; i++)
    q.offer(i * 3);
q.poll();
q.offer(q.poll() + q.peek());
System.out.println(q.peek() + " " + q.size()
                   + " " + q);
while (q.size() > 1)
    q.poll();
System.out.println(q.poll() + " " + q.poll());
Show answer
  • The loop gives [3, 6, 9, 12]; poll() removes 3 → [6, 9, 12].
  • Arguments are evaluated left to right: poll() → 6 (queue [9, 12]), peek() → 9; 15 joins the rear → [9, 12, 15].
  • Front 9, size 3.
  • The while loop discards 9 and 12; then poll() → 15, and since the queue is now empty, the second poll() → null (no exception).

Output:

9 3 [9, 12, 15]
15 null

Short Answer · Array-Based Queues

Question 4: The Trouble with a Simple Array Queue

A simple (non-circular) array queue with capacity N = 6 starts with front = 0, rear = −1. We enqueue 10, 20, 30, 40, call dequeue() three times, and enqueue 50, 60. What are front and rear now, and why does the next enqueue(70) fail?

Show answer
  • Enqueue does rear++ and dequeue does front++; items are never shifted.
  • Four enqueues → rear = 3; three dequeues (10, 20, 30) → front = 3; 50 and 60 → rear = 5.
  • Final state: front = 3, rear = 5; the queue holds 40, 50, 60 (only 3 items).
  • With rear = N − 1 the queue looks “full,” yet indices 0–2 are free, and a simple array queue cannot reuse freed slots.

Fix 1: shift the items left on every dequeue → dequeue is O(n). Fix 2: a circular array, whose index wraps around with (i + 1) % N → every operation is O(1).

Multiple Choice · Array-Based Queues

Question 5: The Insertion Index

A circular queue keeps front (index of the first item), size, and N = data.length. Where does enqueue() write the new item?

The slot after the last item is front + size, and % N wraps it to the start. (front + size − 1) % N is the last item itself; A, without the mod, can run off the array (ArrayIndexOutOfBoundsException). D is the new front after a dequeue.

Multiple Choice · Array-Based Queues

Question 6: Leaving One Slot Empty

A circular queue has no counter and leaves one slot empty (front: first item, rear: next write position). With N = 10, how many items fit at most, and when is the queue full?

front == rear means empty, so one slot always stays free to keep full distinct → N − 1 = 9 items. Using all 10 slots with only front and rear (A) makes an empty and a full queue look identical. The alternative is a size counter (full: size == N).

Code Trace · Array-Based Queues

Question 7: Wraparound in a Circular Queue

In a circular queue of capacity 4, what does the dequeue() on the last line print, and what are front and size at the end?

00front add→010203
00front add→010203

The array is full of 0s but logically empty.

100front01add→0203

enqueue(10): index (0 + 0) % 4 = 0.

100front20102add→03

enqueue(20): index (0 + 1) % 4 = 1.

100front20130203add→

enqueue(30): index (0 + 2) % 4 = 2.

100201front30203add→

dequeue() → 10; front 0 → 1. The value stays in the array but is no longer queued.

100201302front03add→

dequeue() → 20; front 1 → 2. The value stays in the array but is no longer queued.

100add→201302front403

enqueue(40): index (2 + 1) % 4 = 3.

500201add→302front403

enqueue(50): index (2 + 2) % 4 = 0. Past the end of the array, the index wraps around.

500601302front403

enqueue(60): index (2 + 3) % 4 = 1. The index wraps around, and the queue is now full.

500601302add→403front

dequeue() → 30 is printed (the oldest item). Final state: front = 3, size = 3; the queue holds 40, 50, 60.

int[] d = new int[4];
int front = 0, size = 0;
void enqueue(int x) {
    d[(front + size) % d.length] = x;
    size++;
}
int dequeue() {
    int x = d[front];
    front = (front + 1) % d.length;
    size--;
    return x;
}
// enqueue(10); enqueue(20); enqueue(30);
// dequeue(); dequeue();
// enqueue(40); enqueue(50); enqueue(60);
// System.out.println(dequeue());

Short Answer · Array-Based Queues

Question 8: Growing a Full Queue

A full circular queue has data = [F, G, C, D, E], front = 2, size = 5. After enqueue(H), what are the array, front, and size?

private void resize(int newCap) {
  E[] temp = (E[]) new Object[newCap];
  for (int k = 0; k < size; k++)
    temp[k] = data[(front + k) % data.length];
  data = temp;
  front = 0;
}
public void enqueue(E item) {
  if (size == data.length)
    resize(2 * data.length);
  data[(front + size) % data.length] = item;
  size++;
}
Show answer
  • size == 5 → resize(10).
  • k = 0..4: data[2] = C, data[3] = D, data[4] = E, data[0] = F, data[1] = G → temp[0..4] = C, D, E, F, G; front = 0.
  • H: (0 + 5) % 10 = 5 → data[5] = H; size = 6.

Result: [C, D, E, F, G, H, _, _, _, _], front = 0, size = 6. The copy follows the logical order, so the order is preserved. Growing takes O(n), but because the capacity doubles, enqueue is amortized O(1).

Multiple Choice · Array-Based Queues

Question 9: Arrays.copyOf When Growing

A full queue has data = [C, D, A, B], front = 2 (order A, B, C, D). It grows with the line shown, and front is not changed. After enqueue(E), what do five dequeue() calls return, in order?

// this line replaces resize()
data = Arrays.copyOf(data, 2 * data.length);
// front stays 2

copyOf keeps the indices: [C, D, A, B, _, _, _, _], front = 2. E goes to (2 + 4) % 8 = 6, and dequeue reads data[2..6]: A, B, null, null, E. The wrapped C and D are lost. A is what the correct resize gives, copying in (front + k) % N order; D assumes E went to index 4.

Short Answer · Linked Queues

Question 10: A Bug in enqueue

This linked-queue enqueue has a bug. What happens on enqueue(10) and then enqueue(15) from an empty queue, and how is the method fixed?

public void enqueue(int data) {
    Node temp = new Node(data);
    if (isEmpty()) {
        front = temp;
    } else {
        rear.next = temp;
    }
    size++;
}
Show answer
  • enqueue(10): the queue is empty → front = node(10); rear is never assigned and stays null.
  • enqueue(15): not empty → accessing rear.next → NullPointerException.

Fix: after the if/else, the new node must become the rear in both cases:

    }
    rear = temp;      // added
    size++;

The list is never traversed, so every enqueue is O(1).

Short Answer · Kinds of Queues

Question 11: Output of a Deque

ArrayDeque is a double-ended queue; push/pop work at the head. What does the program print?

Deque<String> d = new ArrayDeque<>();
d.offerFirst("A");
d.offerLast("B");
d.push("C");
d.addLast("D");
System.out.print(d.pollLast() + " ");
System.out.print(d.pop() + " ");
d.offerFirst("E");
System.out.print(d.peekLast() + " " + d);
Show answer
  • offerFirst A → [A]; offerLast B → [A, B]
  • push = addFirst → [C, A, B]; addLast D → [C, A, B, D]
  • pollLast → D; pop = removeFirst → C; deque [A, B]
  • offerFirst E → [E, A, B]; peekLast → B (not removed)

Output: D C B [E, A, B]

A deque is not bound to FIFO: used at one end only, it is a stack; in at one end and out at the other, it is a queue.

Short Answer · Kinds of Queues

Question 12: Stacks and Queues from a Deque

What is a deque (double-ended queue)? Which operations make a deque behave like a stack, and which like a queue? What does the code below print?

Deque<Integer> d = new ArrayDeque<>();
d.addFirst(1);
d.addLast(2);
d.addFirst(3);
d.pollLast();
d.addLast(4);
System.out.println(d);
Show answer
  • A deque is a queue that allows insertion and removal at both the front and the rear.
  • Inserting and removing at the same end (e.g., addFirst + pollFirst, or push/pop) gives a stack.
  • Inserting at one end and removing at the other (e.g., addLast + pollFirst) gives a queue.
  • [1] → [1, 2] → [3, 1, 2] → pollLast removes 2 → [3, 1] → [3, 1, 4]

Output: [3, 1, 4]

Multiple Choice · Kinds of Queues

Question 13: The prev Reference

In a deque built on a doubly linked list, why does each node also keep a prev reference?

In a singly linked list, removing the tail means walking from the head to the second-to-last node: O(n). addFirst is O(1) there too (B), and prev adds a reference to every node, so memory grows (D).

Short Answer · Kinds of Queues

Question 14: Sliding Window Maximum

What does windowMax(a, 3) return for a = {4, 2, 1, 3, 6, 2, 1}?

int[] windowMax(int[] a, int k) {
  int[] maxes = new int[a.length - k + 1];
  Deque<Integer> d = new ArrayDeque<>();
  for (int i = 0; i < a.length; i++) {
    if (!d.isEmpty()
        && d.peekFirst() <= i - k)
      d.pollFirst();   // out of window
    while (!d.isEmpty()
           && a[d.peekLast()] <= a[i])
      d.pollLast();    // not a candidate
    d.offerLast(i);
    if (i >= k - 1)
      maxes[i - k + 1] = a[d.peekFirst()];
  }
  return maxes;
}
Show answer
ia[i]d (indices)maxes
040
120, 1
210, 1, 24
333 (0 out of window; 2, 1 dropped)3
4646
524, 56
614, 5, 66

Result: [4, 3, 6, 6, 6]. Values in the deque decrease from front to rear, so the maximum is at the front. Each index enters once and leaves at most once → O(n) (brute force is O(n·k)).

Short Answer · Applications

Question 15: A Round-Robin Scheduler

The ready queue holds P1 (4 units), P2 (7 units), and P3 (2 units), in that order; the time slice (quantum) is q = 3. The process at the front runs for at most q units and, if unfinished, rejoins at the rear. When does each process finish?

Show answer
TimeRunningRemainingQueue (after)
0–3P11P2, P3, P1
3–6P24P3, P1, P2
6–8P30 → doneP1, P2
8–9P10 → doneP2
9–12P21P2
12–13P20 → doneempty

Completion: P3 = 8, P1 = 9, P2 = 13. A process with less time left than the slice does not use all of it. Each round is one poll and at most one offer: O(1).

Code Trace · Applications

Question 16: The Josephus Problem

The queue holds A, B, C, D, E, F from front to rear. In what order does josephus(q, 2) eliminate people, and whom does it return?

qABCDEFfront
qBCDEFAfront

size 6 > 1 → new round. i = 1: A moves to the rear.

qCDEFAfront

B leaves the front and is eliminated. 5 left.

qDEFACfront

size 5 > 1 → new round. i = 1: C moves to the rear.

qEFACfront

D leaves the front and is eliminated. 4 left.

qFACEfront

size 4 > 1 → new round. i = 1: E moves to the rear.

qACEfront

F leaves the front and is eliminated. 3 left.

qCEAfront

size 3 > 1 → new round. i = 1: A moves to the rear.

qEAfront

C leaves the front and is eliminated. 2 left.

qAEfront

size 2 > 1 → new round. i = 1: E moves to the rear.

qEfront

A leaves the front and is eliminated. 1 left.

q(empty)

size 1 → the loop ends; return E. Elimination order B, D, F, C, A; the winner is E. n − 1 rounds of k queue operations each: O(n·k).

String josephus(Queue<String> q, int k) {
  while (q.size() > 1) {
    for (int i = 1; i < k; i++)
      q.offer(q.poll()); // to the rear
    String out = q.poll();
    System.out.println(out + " eliminated");
  }
  return q.poll();
}

Code Trace · Applications

Question 17: A Queue from Two Stacks

After the operations in the comments, what is printed, and how many items in total move from inbox to outbox?

inbox(empty)outbox(empty)
inbox1topoutbox(empty)

enqueue(1): inbox.push(1) → O(1).

inbox21topoutbox(empty)

enqueue(2): inbox.push(2); the top is on the left.

inbox(empty)outbox12top

dequeue: outbox is empty → 2 and 1 move over from inbox. The transfer reverses the order, so the oldest item (1) ends up on top.

inbox(empty)outbox2top

outbox.pop() → 1 is printed (FIFO).

inbox3topoutbox2top

enqueue(3): inbox.push(3). The 2 in outbox is left alone.

inbox3topoutbox(empty)

dequeue: outbox is not empty → no transfer; outbox.pop() → 2.

inbox(empty)outbox3top

dequeue: outbox is empty → the 3 in inbox moves over.

inbox(empty)outbox(empty)

outbox.pop() → 3. Output 1 2 3 matches the input order; 3 transfers in total. Each item is transferred at most once → dequeue is amortized O(1) (a single call is O(n) in the worst case).

Deque<Integer> inbox = new ArrayDeque<>();
Deque<Integer> outbox = new ArrayDeque<>();
void enqueue(int x) {
  inbox.push(x);
}
int dequeue() {
  if (outbox.isEmpty())
    while (!inbox.isEmpty())
      outbox.push(inbox.pop());
  return outbox.pop();
}
// enqueue(1); enqueue(2);
// print(dequeue()); enqueue(3);
// print(dequeue()); print(dequeue());

Multiple Choice · Summary

Question 18: PriorityQueue and FIFO

What does the program print?

Queue<Integer> q = new PriorityQueue<>();
q.offer(5);
q.offer(1);
q.offer(3);
System.out.println(q.poll() + " " + q.poll());

PriorityQueue implements the Queue interface but is not FIFO: poll returns the smallest item (natural order, min-priority) → 1, then 3. Answering “5 1” means expecting arrival order because the variable's type is Queue.

Short Answer · Applications

Question 19: Generating Binary Numbers

What does generateBinary(7) return? What is left in q after the loop, and how many items remain for a general n?

String[] generateBinary(int n) {
    String[] result = new String[n];
    Queue<String> q = new LinkedList<>();
    q.offer("1");
    for (int i = 0; i < n; i++) {
        result[i] = q.poll();
        q.offer(result[i] + "0");
        q.offer(result[i] + "1");
    }
    return result;
}
Show answer
ipoll → result[i]enqueued
0110, 11
110100, 101
211110, 111
31001000, 1001
41011010, 1011
51101100, 1101
61111110, 1111

Returned array: {"1", "10", "11", "100", "101", "110", "111"}.

8 items remain, 1000 through 1111 (8–15). Each round removes 1 item and adds 2 (net +1), starting from 1 item → n + 1 items. FIFO makes the numbers come out level by level, in increasing order.

Multiple Choice · Kinds of Queues

Question 20: An Input-Restricted Deque

1, 2, 3, 4 enter an input-restricted deque in this order, at the rear only; items may leave from the front or the rear at any time. Which removal order is impossible?

D: if 4 comes out first, all four are inside, reading 1 2 3 4 from front to rear; after 4 leaves from the rear, the ends are 1 and 3, so 2 cannot come next. A: insert 1, 2, 3 → rear 3, front 1 → insert 4, rear 4 → 2. B: insert all → rear 4, front 1, rear 3, 2. C: insert 1, 2 → rear 2 → insert 3, 4 → rear 4, front 1, 3.

Multiple Choice · Kinds of Queues

Question 21: An Output-Restricted Deque

1, 2, 3, 4 enter an output-restricted deque in this order, each at the front or the rear; items leave from the front only, at any time. Which output order is impossible?

C: if 4 comes out first, all four are inside, and the output is the deque read from front to rear. Each new number goes to an end, so 3, the largest of 1, 2, 3, must sit at an end; in 1 3 2 it is in the middle. A: 1; 2 front; 3 rear; 4 front. B: 1; 2 rear; 3 front; 4 front. D: 1; 2 rear; 3 front → 3, 1 out → 4 front → 4, 2 out.

Multiple Choice · Array-Based Queues

Question 22: Counting Items with an Empty Slot

A circular queue has no counter and leaves one slot empty (front: first item, rear: next write position). With N = 6, front = 4, and rear = 1, how many items are there, and how many more insertions fit before it is full?

C: the items sit at indices 4, 5, 0: (rear − front + N) % N = (1 − 4 + 6) % 6 = 3. At most N − 1 = 5 fit, so 2 more; then (rear + 1) % 6 == front. B also fills the reserved slot. A takes rear for the last item and counts index 1. D reads front > rear as full, but wrapping around is normal.

Multiple Choice · Array-Based Queues

Question 23: Full or Empty?

No counter is kept and all N = 5 slots are used; front (first item) and rear (next write position) advance % 5. An empty queue has front = rear = 0. After 3 insertions, 1 removal, and 3 more insertions, what is the state?

D: three insertions take rear to 3, the removal takes front to 1, and three more make rear = (3 + 3) % 5 = 1. The queue is full, but an empty queue also has front == rear, so A calls it empty. C forgets the mod (index 6 is off the array); B forgets that a removal advances front. The fix: a size counter (full: size == N) or one empty slot.

The End

Chapter 8: Queues and Deques: Study Questions
Lecture slides: Chapter 8: Queues and Deques
1 / 1 Sercan KÜLCÜ. All rights reserved.