# Lecture 16: Prove recursive progress to a base case ## Prove a smaller call reaches a base case **Instructor:** [Dr. Debasish Pattanayak](https://drdebmath.github.io)
## Each recursive call adds a frame and must eventually return For
factorial(3)
: 1.
factorial(3)
waits for
factorial(2)
. 2.
factorial(2)
waits for
factorial(1)
. 3. The base case returns 1. 4. Waiting frames finish in reverse order.
## Every recursive call moves toward its base case ~~~cpp int factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); } ~~~ The argument decreases, so a non-negative input reaches the base case.
## Recursive reversal rewires one node and delegates the suffix ~~~cpp Node* reverse(Node* head) { if (head == nullptr || head->next == nullptr) return head; Node* newHead = reverse(head->next); head->next->next = head; head->next = nullptr; return newHead; } ~~~
## Backtracking explores, recurses, and undoes each choice Choose one value for the current position, recursively arrange the remainder, then undo the choice. The data structure is an array; recursion supplies the search order.
## Memoization avoids repeated subproblems in LCS For two strings, an LCS recurrence compares their final characters and reduces one or both prefixes. The direct recursive version repeats subproblems. Memoization stores results so identical states are solved once.
## Recursion trades stack space and repeated work for clarity - Recursive list reversal: O(n) time, O(n) call-stack space. - Iterative reversal: O(n) time, O(1) auxiliary space. - Permutation generation: at least proportional to the number of produced permutations. Complexity describes growth, not stopwatch seconds.
## Prove termination, trace frames, and measure recursive cost - A recursive call must receive a smaller problem. - A base case handles the smallest problem directly. - Stack frames consume space. - Recursion can expose natural structure, while iteration may use less memory.