Week 9: Recursion (Layered)

2417 words
12 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Week 9: Recursion — Call Stacks, Invariants, and Unwinding > [!SUMMARY] > **Sitting Scope:** 45–60 minutes. Complete conceptual grounding, call-stack anatomy, exam pattern dissection, and attempt-first practice drills.

Week 9: Recursion — Call Stacks, Invariants, and Unwinding

Summary
Sitting Scope: 45–60 minutes. Complete conceptual grounding, call-stack anatomy, exam pattern dissection, and attempt-first practice drills.

1. Orientation & Where It Sits

In procedural thinking, repetition is traditionally handled through loops (While or For). Recursion introduces a fundamentally different cognitive framework: instead of advancing a mutable counter forward, we decompose a problem into an identical subproblem of smaller magnitude, delegating the subproblem until reaching a trivial terminal boundary.
[Procedures & Parameters] (Week 3) ──┐
                                     ├──► [Recursion & Call Stacks] (Week 9) ──► [Depth-First Search] (Week 9/10)
[Lists & Sequences]       (Week 5) ──┘                                        └──► [PDSA Divide & Conquer] (Diploma)
  • Prerequisites:
  • Downstream Unlocks:
    • Depth-First Search (DFS) — Recursive graph traversal, backtracking, and visited sets.
    • Divide-and-Conquer Algorithms — Merge Sort, Quick Sort, and recurrence relations (T(n)=2T(n/2)+O(n)T(n) = 2T(n/2) + O(n)).

2. Notation, Vocabulary & Etymology

TermPronunciation & SyntaxSemantic MeaningMemory Hook
Recursionree-KUR-zhunA procedure definition that invokes an instance of itself on a strictly reduced domain.Latin recurrere ("to run back"). The execution runs back to its own definition.
Base Caseif (n == 0) return 1The non-recursive branch providing an immediate, constant-time solution for the minimal valid input.The bedrock foundation. Without it, you drill indefinitely into bedrock.
Call StackStack memory frameA LIFO (Last-In, First-Out) data structure managed by runtime to track active function calls and their local scopes.A stack of plates in a cafeteria: you can only place or pick from the very top.
Stack FrameActivation recordThe dedicated memory block holding local variables, parameter copies, and return addresses for one specific invocation.A sealed envelope containing the private scratch-pad for one specific sub-problem.
UnwindingBubble-up phaseThe phase after a base case is hit where suspended caller frames resume, receive returned values, and resolve.Rewinding a dropped ball of yarn back up the staircase.

3. Layered Conceptual Depth

Layer 1: The Intuition — The Bureaucratic Chain

Imagine an office tasked with tallying 100100 audit forms.
  1. Officer A receives 100100 forms. Rather than counting all 100100, Officer A takes one form, determines its value, and hands the remaining 9999 forms to Assistant B with the instruction: "Tally these 9999 and report your total to me; I will add my 1 and report to the director."
  2. Assistant B does the same: takes 11 form, passes 9898 forms to Deputy C.
  3. This sequence continues down the chain until Clerk Z receives exactly 00 forms. Clerk Z does not delegate. Clerk Z immediately declares: "My total is 00!"
  4. Now the unwinding begins: Deputy Y receives 00, adds their 11 form, reports 11 upward. Assistant B receives 9898, adds 11, reports 9999 to Officer A. Officer A adds 11, yielding 100100.
Notice the two distinct phases:
  1. The Descent (Winding Phase): Work is deferred, frames are pushed onto the call stack, inputs shrink.
  2. The Resolution (Unwinding Phase): The base case returns a value, suspended frames compute their combined result in reverse order, frames are popped off the stack.

For any recursive procedure to be computationally sound and terminate in finite steps, it must satisfy three mathematical invariants:
  1. Reachable Base Case: There must exist at least one conditional branch that does not call the procedure itself and instead terminates with a direct return.
  2. Strict Monotonic Progress (Convergence): Every recursive call must pass arguments strictly closer to the base case according to a well-founded metric (e.g., n−1n - 1, n//2n // 2, Tail(L)\text{Tail}(L)).
  3. Correct Recombination Logic: Assuming the recursive call correctly solves the subproblem (the Inductive Hypothesis), the procedure must correctly combine that sub-solution with the current step's data.

Layer 3: Call Stack Architecture & Execution Lifecycle

Consider computing SumUpTo(3) where:
pseudo
Procedure SumUpTo(n)
    if (n == 0) {
        return 0
    }
    return n + SumUpTo(n - 1)
End SumUpTo

Step-by-Step Stack Frame Lifecycle

[Stack Growth - Descent]                         [Base Hit]      [Stack Collapse - Unwind]

Frame 3: n=3 -> calls SumUpTo(2)                 Frame 0: n=0    Frame 1 resumes: 1 + 0 = 1
Frame 2: n=2 -> calls SumUpTo(1)                 returns 0!      Frame 2 resumes: 2 + 1 = 3
Frame 1: n=1 -> calls SumUpTo(0)                                 Frame 3 resumes: 3 + 3 = 6
Frame 0: n=0 -> Base Case Hit!                                   Final Answer: 6

Memory Trace Table

PhaseActive FrameParameter nnLocal Execution StateCall Stack Depth
PushSumUpTo(3)33Suspended at 3 + SumUpTo(2)11
PushSumUpTo(2)22Suspended at 2 + SumUpTo(1)22
PushSumUpTo(1)11Suspended at 1 + SumUpTo(0)33
Base HitSumUpTo(0)00Evaluates if (n == 0) →\to returns 0044 (Peak)
Pop & ResolveSumUpTo(1)11Evaluates 1 + 0 →\to returns 1133
Pop & ResolveSumUpTo(2)22Evaluates 2 + 1 →\to returns 3322
Pop & ReturnSumUpTo(3)33Evaluates 3 + 3 →\to returns 661→01 \to 0

4. Worked Anatomy: Trace Dissection

Let us dissect an authentic IITM Computational Thinking exam archetype: tracking nested list processing with accumulator side-states.

The Problem

pseudo
Procedure Puzzle(A, n)
    if (n == 1) {
        return A[1]
    }
    prev = Puzzle(A, n - 1)
    if (A[n] > prev) {
        return A[n]
    } else {
        return prev
    }
End Puzzle
Given list A=[12,45,23,67,34]A = [12, 45, 23, 67, 34] (1-indexed) and called with Puzzle(A, 5).

Dissection Trace

  1. Call 1: Puzzle(A, 5). n=5≠1n = 5 \neq 1. Calls Puzzle(A, 4). Frame 1 pauses.
  2. Call 2: Puzzle(A, 4). n=4≠1n = 4 \neq 1. Calls Puzzle(A, 3). Frame 2 pauses.
  3. Call 3: Puzzle(A, 3). n=3≠1n = 3 \neq 1. Calls Puzzle(A, 2). Frame 3 pauses.
  4. Call 4: Puzzle(A, 2). n=2≠1n = 2 \neq 1. Calls Puzzle(A, 1). Frame 4 pauses.
  5. Call 5 (Base Case): Puzzle(A, 1). n=1n = 1. Returns A[1]=12A[1] = 12.
  6. Unwinding Frame 4: Receives prev = 12. Compares A[2]A[2] (4545) vs 1212. Since 45>1245 > 12, returns 4545.
  7. Unwinding Frame 3: Receives prev = 45. Compares A[3]A[3] (2323) vs 4545. Since 23≯4523 \not> 45, returns prev = 4545.
  8. Unwinding Frame 2: Receives prev = 45. Compares A[4]A[4] (6767) vs 4545. Since 67>4567 > 45, returns 6767.
  9. Unwinding Frame 1: Receives prev = 67. Compares A[5]A[5] (3434) vs 6767. Since 34≯6734 \not> 67, returns prev = 6767.
Semantic Realization: Puzzle(A, n) computes the maximum element in A[1…n]A[1 \dots n]. Every step reduces the search span by 11, solves the prefix maximum, and compares the boundary element.

5. Non-Examples & The 3 Ways Recursion Fails

A recursive implementation fails in one of three canonical manners:
                  ┌── 1. Infinite Descent (Missing / Unreachable Base Case)
                  │
Recursion Fails ──┼── 2. Divergent / Stagnant Reduction (Argument Does Not Shrink)
                  │
                  └── 3. Aliased In-Place Mutation (Shared State Corruption)

1. The Missing or Unreachable Base Case

pseudo
Procedure CountDown(n)
    if (n == 0) return 0
    return CountDown(n - 2) // FAILS if n is odd! (e.g., n=3 -> 1 -> -1 -> -3 ...)
If
nn starts as an odd integer, the condition n == 0 is never satisfied! The procedure skips directly from n=1n = 1 to n=−1n = -1, causing unbounded stack expansion until terminating with a Stack Overflow. Fix: Use boundary inequalities: if (n <= 0) return 0.

2. Stagnant Reduction (Non-Progress)

pseudo
Procedure LoopTrap(n)
    if (n == 1) return 1
    return LoopTrap(n) // FAILS: argument remains n, zero progress made

3. State Corruption via Shared References

In languages with mutable objects (like Python lists), passing a mutable list and modifying it inside recursive branches without copying causes sibling calls to see dirty state. In CT pseudocode, ensure each level respects procedural parameter purity.

6. Question-Pattern Anatomy (8 Exam Reflexes)

In IITM BS DS Computational Thinking quizzes and end-term examinations, recursion questions follow eight predictable structural patterns:
#Pattern NameRecognition CueStandard Attack SequenceThe Planted Trap
P1Linear Trace & OutputSingle self-call, simple arithmetic n-1Draw the stack downward to base case, unwind upwardsAdding the base case return value twice
P2Tree Branching (Double Call)Two calls per frame: F(n-1) + F(n-2)Draw binary recursion tree; count total nodes or leaf evaluationsCalculating O(n)O(n) instead of O(2n)O(2^n) calls
P3Pre vs Post ExecutionStatements before vs after the recursive callPre-statements execute top-to-bottom (n…1n \dots 1); Post-statements execute bottom-to-top (1…n1 \dots n)Inverting print/output order
P4Base Case Parity TrapStep decrement of 22 (n - 2)Test both an even number (n=4n=4) and an odd number (n=5n=5)Assuming it always terminates
P5Accumulator ParameterExtra parameter acc passed in call F(n-1, acc + n)State flows forward down the stack; base case returns final acc directlyExpecting unwinding arithmetic that never happens
P6String / List SlicingSlicing string S[1:] or list Head/TailCheck length reduction; identify whether operation prepends or appendsOff-by-one error on empty string vs single char
P7Call Count NATQuestion asks: "How many times is Procedure F called?"Count the root call (11) plus calls generated by each childForgetting to count the initial top-level invocation
P8Loop-to-Recursion EquivalenceCode snippet asks which recursive block matches a While loopMap loop condition to base negation; map loop increment to recursive argumentMismatching the pre-loop initial state

7. Interactive Attempt-First Checks

Test your active recall and execution tracing reflexes. Commit your answer before reading the solution.
1

Question 1

Type: MCQ | Marks: 1 | Topic: Pre vs Post Recursion Execution Order
Consider the following CT procedure:
pseudo
Procedure PrintPattern(n)
    if (n > 0) {
        Print(n)
        PrintPattern(n - 1)
        Print(n)
    }
End PrintPattern
What is the exact output printed when PrintPattern(3) is executed?
MCQ
Pre vs Post Recursion Execution Order
3 Unit Assessment
A
3 2 1 1 2 3
B
3 2 1 0 1 2 3
C
1 2 3 3 2 1
D
3 3 2 2 1 1

2

Question 2

Type: NAT | Marks: 1 | Topic: Invocation Counting in Branching Recursion
Consider the procedure below:
pseudo
Procedure Branch(n)
    if (n <= 1) {
        return 1
    }
    return Branch(n - 1) + Branch(n - 2)
End Branch
How many total times is the procedure Branch invoked when evaluating Branch(4)? Enter an integer.
NAT
3 Unit Assessment

3

Question 3

Type: MCQ | Marks: 1 | Topic: Recursive Return State Analysis
What does the following recursive function return when passed a non-negative integer nn?
pseudo
Procedure Mystery(n)
    if (n == 0) {
        return 0
    }
    return (n % 10) + Mystery(n // 10)
End Mystery
MCQ
Recursive Return State Analysis
3 Unit Assessment
A
The number of digits in nn
B
The reverse of the digits of nn
C
The sum of the digits of nn
D
The highest digit in nn

Blank-Page Feynman Active Recall

Close this document. Take a blank sheet of paper and answer this single question without looking at notes:
"Why does execution pause when a recursive call is made, where does the computer store the variables of the paused function, and what triggers the computer to resume them?" If you can cleanly describe frames, stack push, base return, and unwinding, you own the concept.

8. Next Action & Spacing Protocol

  • Immediate Next Chapter: Week 9: Depth-First Search (DFS) — Apply call-stack mechanics to graph exploration and back-tracking.
  • Active Drill Desk: Open the Quiz 3 Checkpoint Desk to practice Computational Thinking timed mocks.
  • Spaced Review Suggestion: Re-attempt Question 2 on blank paper after 48 hours to reinforce tree branch counting.

Provenance: Authored from scratch adhering to the Learning OS Authoring Cookbook standard (docs/authoring/AUTHORING_COOKBOOK.md). Original imported reference 818 - Week 9- Recursion.md preserved intact.
Document outline

Keep your place and jump directly to a heading.

Table of contents

No note selected

Open a chapter to see its outline, backlinks, and sources here.