Recursion and Trees
68 / 170Recursion and TreesLesson 1 of 13About 45 min
No problems in this lesson. It exists because everything after it, and both of the hardest units later, assume it.
If you already write recursion comfortably, this will take ten minutes and the drills will still be worth doing. If you do not, this is the most important lesson in the course, because backtracking and dynamic programming are both recursion with extra bookkeeping, and neither is learnable while recursion itself is shaky.
Each call gets its own copy of the local variables, stacked on top of the caller's. When a call returns, its frame is discarded and the caller resumes exactly where it left off.
The depth of that stack is the space cost of a recursion, which is why an O(n) recursion can use O(n) space even when it allocates nothing. Python stops you at a depth around a thousand by default, which is a real constraint on some problems and never an issue on balanced trees.
import sysprint(sys.getrecursionlimit()) def depth_of(n): if n == 0: return 0 return 1 + depth_of(n - 1) print(depth_of(900))try: depth_of(10000)except RecursionError: print("RecursionError")The same recursion prints in two different places. Type both lines of output, each as digits separated by single spaces.
def down(n): if n == 0: return print(n, end=" ") down(n - 1) def up(n): if n == 0: return up(n - 1) print(n, end=" ") down(4)print()up(4)print()Four small recursions, no trees yet. Write each one recursively even where a loop would be shorter, because the point is the shape. count_down builds a list from n to 1. sum_digits adds the digits of a non-negative integer. is_palindrome checks a string. flatten turns a nested list of lists into a flat list.
Tests
print(count_down(4), count_down(0))print(sum_digits(1234), sum_digits(0))print(is_palindrome("racecar"), is_palindrome("abca"), is_palindrome(""))print(flatten([1, [2, [3, 4]], 5]), flatten([]))Output
Run tests to see output.