Pre-Midterm Revision
Six sections, one pass. Recall the rules, predict an output, repair broken code, watch the structure move, then write it yourself.
- 01Arrays
- 02Linked Lists
- 03Recursion
- 04Stacks
- 05Queues
- 06Binary Search Trees
Five Ideas, One Screen
Five ideas to have ready before the questions start. No new material — just the array rules the exam expects you to recall instantly.
arr[i] — a single row of cells.arr[row][col] — a table of rows and columns.0; the last is n - 1.arr[i]; modify with arr[i] = value.for (int i = 0; i < n; i++) visits every cell once.| arr | col 0 | col 1 |
|---|---|---|
| row 0 | 84 | 78 |
| row 1 | 92 | 97 |
| row 2 | 88 | 91 |
arr[1] is the second cell — the index is an offset from the start.Read It Before You Run It
Two cells are changed, then the whole array is summed. What exactly does this program print?
Find It, Then Fix It
Press Reveal fix to repair one line at a time. The corrected line turns green in the code panel, and the card beside it keeps the before/after pair.
i <= size→i < sizeWhen size is 5, i <= size reads arr[5] — one cell past the array. The loop must stop before size.
scores[i + 1]→scores[i]The loop is meant to add the first three scores, but i + 1 skips scores[0] and adds 80, 90 and 60 instead.
scores[5] = 100→scores[4] = 100The last valid cell is scores[4]. Writing to scores[5] goes past the end of the array.
scores[0..4], and the first three scores add to 240.Read the Table
Each expression points at one cell. Predict its value, then reveal the cell and check the highlight.
| arr | Exam 1 | Exam 2 | Exam 3 |
|---|---|---|---|
| Student 1 | 84 | 78 | 90 |
| Student 2 | 92 | 97 | 85 |
| Student 3 | 88 | 91 | 79 |
arr[0][1]→?PREDICTarr[2][0]→?PREDICTarr[1][2]→?PREDICTarr[1][2] means row 1, column 2 — not row 1, column 3.Write It Line by Line
Three tasks, one array. Write each loop yourself first, then use the stepper to reveal the solution one line at a time and check your structure.
| a | col 0 | col 1 | col 2 |
|---|---|---|---|
| row 0 | 8 | 6 | 10 |
| row 1 | 4 | 9 | 8 |
| row 2 | 12 | 6 | 3 |
int a[3][3] is already declared with these values.Pointers, Not Boxes
Nothing here is new. Five pointer rules, applied six times — insert, delete, and the two operations that only read.
- 02.1Pointer Contract
- 02.2Predict the Output
- 02.3Find the Bug
- 02.4Insert at a Position
- 02.5Write the Code
The Pointer Contract
Every insert, delete and search in this section is just these five rules being restored after something changed.
data value and a next pointer — the value, and the address that follows it.nullptr only when the list is empty.nullptr only when the list is empty.next is always nullptr.next until it is nullptr.next pointer is not reassigned, nothing moves. A link only exists once it is written.Six Calls, One List
Track head and tail after each call. The position argument is 1-based; the loop that finds it is not.
insertAtPosition(15, 3) inserts after the second node, not before the third.Find It, Then Fix It
Three pointer bugs. Press Reveal fix to repair one line at a time — the corrected line turns green, and the card keeps the before/after pair.
i < position→i < position - 1The loop must stop on the predecessor. With i < position it stops one node too far, so the new node lands after the wrong node.
newNode->next = newNode→newNode->next = temp->nextPointing the new node at itself creates a one-node loop. It must first capture the node it is pushing forward, then the predecessor is re-linked.
tail = temp->next→tail = tempAfter deleting the last node, the new tail is the predecessor — temp. Assigning temp->next sets tail to nullptr while the list is not empty.
tail always names a node that exists.The Order Is the Lesson
The new node has to point forward before the predecessor points at it. Reverse the two assignments and the rest of the list is lost.
Write It Line by Line
Three methods, three different failure points. Write each one first, then reveal the solution one line at a time.
head and tail.head before freeing, and reset tail if the list empties.nullptr means not found.Node and the class with head / tail already exist.A Function That Trusts Itself
Three parts every time: a base case that stops, a smaller call that moves, and a stack that unwinds.
- 03.1The Contract
- 03.2Predict the Output
- 03.3Find the Bug
- 03.4The Call Stack
- 03.5Write the Code
Three Rules, No Exceptions
A recursive function is not a loop written differently. It is a contract with three clauses, and a missing clause shows up as a crash.
fact(4) = 4 × 3 × 2 × 1 × 1 = 24. The final 1 is the base case, not a multiplication.Two Functions, One Chain
Neither function calls itself — they call each other. Follow the argument down, not the name of the function.
Find It, Then Fix It
Three functions, three broken clauses of the contract. Press Reveal fix to repair one line at a time.
return 0→return 1The base case stops the recursion but answers the wrong number. fact then multiplies by 0, so every result becomes 0.
if (exp == 1)→if (exp == 0)power(x, 0) must return 1. With exp == 1 the call for 0 never matches, keeps subtracting, and runs past zero.
countdown(n)→countdown(n - 1)The same argument goes to every call, so n never reaches 0 and the base case is never seen. The stack grows until it overflows.
Watch It Unwind
Every call pauses at num * fact(num - 1) and waits. Nothing is multiplied until the base case returns the first value.
Start — main calls fact(4). Nothing is on the stack yet.
Write It Line by Line
Three recursion shapes: a value, a void printer, and a mutually recursive pair. Write each one first, then reveal the solution.
One End, No Exceptions
Everything happens at the top. An array stack can fail in exactly two ways: it is full, or it is empty.
- 04.1The LIFO Contract
- 04.2Predict the Output
- 04.3Find the Bug
- 04.4Push & Pop
- 04.5Write the Code
Five Operations, One Index
A stack is an array plus one integer. Every operation is a guard, a move of top, and one read or write.
top moves up before the write.top moves down.arr[top] without moving anything.top == -1 means empty.top == MAX - 1 means full.top is the only thing the class keeps. The values live in arr; the meaning lives in the index.Five Cells, One Wasted Push
Track top, not the values. A pop frees a cell, and capacity is counted from the index, not from how many calls you have made.
top is a counter, so capacity is a state, not the number of elements printed.Find It, Then Fix It
Three methods, one broken line each. Press Reveal fix to repair them in order — the corrected line turns green.
arr[top] = value→arr[++top] = valueThe first push writes arr[-1] because top starts at -1. It must move up before the value is stored.
top++→top--The value is printed correctly but the stack never shrinks, so the same value is popped forever.
top == MAX→top == MAX - 1Index MAX does not exist, so the guard never fires in time and the next write lands past the array.
top moves in the right direction, at the right moment, and stops at the last valid cell.Watch top Move
Both operations touch one cell and one index. Only the order of the two steps changes.
display() starts at i = top and walks down to 0: 30, then 20, then 10.
Write It Line by Line
Three methods, one index between them. Write each one first, then reveal the solution one line at a time.
top, then write.top.arr[MAX] and top already exist.First In, First Out
The front only moves forward. That single fact creates both the simple queue and the circular fix.
- 05.1The FIFO Contract
- 05.2Predict the Output
- 05.3Find the Bug
- 05.4The Wrap-Around
- 05.5Write the Code
Two Pointers, One Direction
A queue is two indices on one array. Every operation is a guard plus a pointer move — and the guard is where the marks are usually lost.
rear, the only place new work enters.front, the only place work leaves.rear == SIZE - 1; space at the front is never reused.(rear + 1) % C_SIZE == front, which also catches the wrap case.front == -1.front only ever increases. The two cells behind it still hold values, but nothing will ever read them again.Full With Three Free Cells
Five cells, three values. Trace front and rear after every call — the last enqueue is the one that matters.
rear wrap back to cell 0.Find It, Then Fix It
A circular queue with three defects, all in the pointer arithmetic. Press Reveal fix to repair one line at a time.
rear++→rear = (rear + 1) % C_SIZEWithout the modulo the rear walks off the end of the array instead of wrapping to 0. The next write lands outside items[].
front = rear = 0→front = rear = -1After the last element leaves, both pointers must return to -1 or the queue can never be empty again — isEmpty() tests front == -1.
rear + 1 == front→(rear + 1) % C_SIZE == frontThe full check must wrap too, or it misses the case where rear sits on the last cell and the only free slot is index 0.
The Array Becomes a Ring
Five cells, five values. Two dequeues and two enqueues are enough to leave the rear sitting behind the front.
Write It Line by Line
Three methods, three pointer moves that must be wrapped. Write each one first, then reveal the solution one line at a time.
% C_SIZE — the rear when inserting, the front when removing, and the walk in display().Order Is the Structure
A BST is not a shape you draw. It is one ordering rule, applied recursively at every node.
- 06.1The Ordering Rule
- 06.2Predict the Output
- 06.3Find the Bug
- 06.4Building the Tree
- 06.5Write the Code
One Rule, Applied Everywhere
Everything in this section is one sentence read in a different order. Get the sentence right and the traversals write themselves.
data, left, right — a leaf has two nullptrs.1 + count(left) + count(right).Children Before the Parent
The three recursive calls only differ in where the print sits. Here the print is last, so nothing is printed until both subtrees are done.
Find It, Then Fix It
Three defects in one insert and one search. Press Reveal fix to repair one line at a time — the corrected line turns green, and the card keeps the before/after pair.
value > root->data→value < root->dataWith the comparison inverted, larger values go left, so the tree no longer satisfies its own rule.
else root = root->left→else root = root->rightSearch follows the left child twice, so the whole right subtree is unreachable.
return true→return falseFalling out of the loop means the key was never found; returning true makes every miss a success.
false.One Comparison per Level
Insert never redraws the tree. It compares once per level and stops at the first empty pointer it reaches.
Write It Line by Line
Three functions, one rule. Write each one first, then reveal the solution one line at a time and check where the recursion returns.
nullptr.Best Wishes!
Good Luck in Your Midterm Exam
You've got this. Do your best!
Good luck in your midterm.
Best Wishes!
Good Luck in Your Midterm Exam
You've got this. Do your best!