Chapter 8: Queues and Deques
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
whileloop discards 9 and 12; thenpoll()→ 15, and since the queue is now empty, the secondpoll()→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 doesfront++; 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 − 1the 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?
The array is full of 0s but logically empty.
enqueue(10): index (0 + 0) % 4 = 0.
enqueue(20): index (0 + 1) % 4 = 1.
enqueue(30): index (0 + 2) % 4 = 2.
dequeue() → 10; front 0 → 1. The value stays in the array but is no longer queued.
dequeue() → 20; front 1 → 2. The value stays in the array but is no longer queued.
enqueue(40): index (2 + 1) % 4 = 3.
enqueue(50): index (2 + 2) % 4 = 0. Past the end of the array, the index wraps around.
enqueue(60): index (2 + 3) % 4 = 1. The index wraps around, and the queue is now full.
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);rearis never assigned and staysnull.enqueue(15): not empty → accessingrear.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
offerFirstA → [A];offerLastB → [A, B]push=addFirst→ [C, A, B];addLastD → [C, A, B, D]pollLast→ D;pop=removeFirst→ C; deque [A, B]offerFirstE → [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, orpush/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] →
pollLastremoves 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
| i | a[i] | d (indices) | maxes |
|---|---|---|---|
| 0 | 4 | 0 | |
| 1 | 2 | 0, 1 | |
| 2 | 1 | 0, 1, 2 | 4 |
| 3 | 3 | 3 (0 out of window; 2, 1 dropped) | 3 |
| 4 | 6 | 4 | 6 |
| 5 | 2 | 4, 5 | 6 |
| 6 | 1 | 4, 5, 6 | 6 |
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
| Time | Running | Remaining | Queue (after) |
|---|---|---|---|
| 0–3 | P1 | 1 | P2, P3, P1 |
| 3–6 | P2 | 4 | P3, P1, P2 |
| 6–8 | P3 | 0 → done | P1, P2 |
| 8–9 | P1 | 0 → done | P2 |
| 9–12 | P2 | 1 | P2 |
| 12–13 | P2 | 0 → done | empty |
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?
size 6 > 1 → new round. i = 1: A moves to the rear.
B leaves the front and is eliminated. 5 left.
size 5 > 1 → new round. i = 1: C moves to the rear.
D leaves the front and is eliminated. 4 left.
size 4 > 1 → new round. i = 1: E moves to the rear.
F leaves the front and is eliminated. 3 left.
size 3 > 1 → new round. i = 1: A moves to the rear.
C leaves the front and is eliminated. 2 left.
size 2 > 1 → new round. i = 1: E moves to the rear.
A leaves the front and is eliminated. 1 left.
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?
enqueue(1): inbox.push(1) → O(1).
enqueue(2): inbox.push(2); the top is on the left.
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.
outbox.pop() → 1 is printed (FIFO).
enqueue(3): inbox.push(3). The 2 in outbox is left alone.
dequeue: outbox is not empty → no transfer; outbox.pop() → 2.
dequeue: outbox is empty → the 3 in inbox moves over.
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
| i | poll → result[i] | enqueued |
|---|---|---|
| 0 | 1 | 10, 11 |
| 1 | 10 | 100, 101 |
| 2 | 11 | 110, 111 |
| 3 | 100 | 1000, 1001 |
| 4 | 101 | 1010, 1011 |
| 5 | 110 | 1100, 1101 |
| 6 | 111 | 1110, 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.