BBM 101. Introduction to Programming I. Lecture #06 Recursion

Similar documents
61A Lecture 7. Monday, September 16

61A Lecture 6. Monday, February 2

61A Lecture 7. Monday, September 15

Recursion Chapter 3.5

Fruitful Recursion (recursion that returns a value)

Overview. What is recursion? When one function calls itself directly or indirectly.

Admin. How's the project coming? After these slides, read chapter 13 in your book. Quizzes will return

CS 112 Introduction to Programming

6.001 Notes: Section 4.1

Recursion CS GMU

Department of Computer Science Yale University Office: 314 Watson Closely related to mathematical induction.

Recursive Definitions

Emil Sekerinski, McMaster University, Winter Term 16/17 COMP SCI 1MD3 Introduction to Programming

2.3 Recursion. Overview. Mathematical Induction. What is recursion? When one function calls itself directly or indirectly.

i.e.: n! = n (n 1)

More Complicated Recursion CMPSC 122

Introduction to Python Programming

CS 310 Advanced Data Structures and Algorithms

RECURSION. Many Slides from Ken Birman, Cornell University

Identify recursive algorithms Write simple recursive algorithms Understand recursive function calling

CMSC 132: Object-Oriented Programming II. Recursive Algorithms. Department of Computer Science University of Maryland, College Park

Recursion. Recursion is: Recursion splits a problem:

The power of logarithmic computations. Recursive x y. Calculate x y. Can we reduce the number of multiplications?

Recursion. Overview. Mathematical induction. Hello recursion. Recursion. Example applications. Goal: Compute factorial N! = 1 * 2 * 3...

2.3 Recursion. Overview. Greatest Common Divisor. Greatest Common Divisor. What is recursion? When one function calls itself directly or indirectly.

DM536 Introduction to Programming. Peter Schneider-Kamp.

2.3 Recursion. Overview. Greatest Common Divisor. Greatest Common Divisor. What is recursion? When one function calls itself directly or indirectly.

Intro. Speed V Growth

BBM 101 Introduc/on to Programming I Fall 2014, Lecture 7. Aykut Erdem, Erkut Erdem, Fuat Akal

APCS-AB: Java. Recursion in Java December 12, week14 1

Lecture 6 CS2110 Spring 2013 RECURSION

34. Recursion. Java. Summer 2008 Instructor: Dr. Masoud Yaghini

Algorithms and Programming

Recursion. Fundamentals of Computer Science

Design and Analysis of Algorithms Prof. Madhavan Mukund Chennai Mathematical Institute. Module 02 Lecture - 45 Memoization

Recursion CSCI 136: Fundamentals of Computer Science II Keith Vertanen Copyright 2011

Anatomy of a static method, S&W, 2.1, figure page 188. Class.name or just name Scope, S&W, 2.1, figure page 189. Overloading

Introduction to Programming I

Recursion and Induction

Algorithm Design and Recursion. Search and Sort Algorithms

DM502 Programming A. Peter Schneider-Kamp.

Agenda. The worst algorithm in the history of humanity. Asymptotic notations: Big-O, Big-Omega, Theta. An iterative solution

n! = 1 * 2 * 3 * 4 * * (n-1) * n

Announcements. Recursion and why study it. Recursive programming. Recursion basic idea

ENVIRONMENT DIAGRAMS AND RECURSION 2

Chapter Summary. Mathematical Induction Recursive Definitions Structural Induction Recursive Algorithms

61A Lecture 19. Wednesday, October 12

Chapter 3 Programming with Recursion

Reading 8 : Recursion

Lecture Notes 4 More C++ and recursion CSS 501 Data Structures and Object-Oriented Programming Professor Clark F. Olson

OVERVIEW. Recursion is an algorithmic technique where a function calls itself directly or indirectly. Why learn recursion?

9/16/14. Overview references to sections in text RECURSION. What does generic mean? A little about generics used in A3

! New mode of thinking. ! Powerful programming paradigm. ! Mergesort, FFT, gcd. ! Linked data structures.

UNIT 5A Recursion: Basics. Recursion

Announcements. CS243: Discrete Structures. Strong Induction and Recursively Defined Structures. Review. Example (review) Example (review), cont.

SCHEME 10 COMPUTER SCIENCE 61A. July 26, Warm Up: Conditional Expressions. 1. What does Scheme print? scm> (if (or #t (/ 1 0)) 1 (/ 1 0))

CSCE 110 Dr. Amr Goneid Exercise Sheet (7): Exercises on Recursion

COMP-202: Foundations of Programming. Lecture 13: Recursion Sandeep Manjanna, Summer 2015

RECURSION: n. SEE RECURSION 3

Lecture 7 CS2110 Fall 2014 RECURSION

Recursion. Recursion [Bono] 1

Blowing a gasket. Recursion. Classic recursive examples. CS112 Scientific Computation Department of Computer Science Wellesley College

CSC 148 Lecture 3. Dynamic Typing, Scoping, and Namespaces. Recursion

DM550/DM857 Introduction to Programming. Peter Schneider-Kamp

Recursion. What is Recursion? Simple Example. Repeatedly Reduce the Problem Into Smaller Problems to Solve the Big Problem

DM536 / DM550 Part 1 Introduction to Programming. Peter Schneider-Kamp.

Lecture 10: Recursion vs Iteration

Recursive definition: A definition that is defined in terms of itself. Recursive method: a method that calls itself (directly or indirectly).

Monty Python and the Holy Grail (1975) BBM 101. Introduction to Programming I. Lecture #03 Introduction to Python and Programming, Control Flow

Module 05: Types of recursion

Mathematical Induction

Recursion vs Induction

CS1 Lecture 15 Feb. 19, 2018

1KOd17RMoURxjn2 CSE 20 DISCRETE MATH Fall

1 Recursion. 2 Recursive Algorithms. 2.1 Example: The Dictionary Search Problem. CSci 235 Software Design and Analysis II Introduction to Recursion

Recursion & Performance. Recursion. Recursion. Recursion. Where Recursion Shines. Breaking a Problem Down

Recursion. Tjark Weber. Functional Programming 1. Based on notes by Sven-Olof Nyström. Tjark Weber (UU) Recursion 1 / 37

Recursion. So, just as you are allowed to call function B from within function A, you are ALSO allowed to call function A from within function A!

Programming & Data Structure

ECE G205 Fundamentals of Computer Engineering Fall Exercises in Preparation to the Midterm

Unit #2: Recursion, Induction, and Loop Invariants

Recursion. CSE 2320 Algorithms and Data Structures University of Texas at Arlington

26 Feb Recursion. Overview. Greatest Common Divisor. Greatest Common Divisor. Greatest Common Divisor. Greatest Common Divisor

Recursion vs Induction. CS3330: Algorithms The University of Iowa

CS/ENGRD 2110 Object-Oriented Programming and Data Structures Spring 2012 Thorsten Joachims. Lecture 10: Asymptotic Complexity and

CSE 230 Intermediate Programming in C and C++ Recursion

CS1 Lecture 15 Feb. 18, 2019

Lecture 1. 1 Notation

Lecture P6: Recursion

q To develop recursive methods for recursive mathematical functions ( ).

q To develop recursive methods for recursive mathematical functions ( ).

a b c d a b c d e 5 e 7

Recursion. Dr. Jürgen Eckerle FS Recursive Functions

CHAPTER 4 FUNCTIONS. Dr. Shady Yehia Elmashad

Reduction & Recursion Overview

Week - 03 Lecture - 18 Recursion. For the last lecture of this week, we will look at recursive functions. (Refer Slide Time: 00:05)


Recursion. Lars-Henrik Eriksson. Functional Programming 1. Based on a presentation by Tjark Weber and notes by Sven-Olof Nyström

HOMEWORK FILE SOLUTIONS

ANS:

Transcription:

BBM 101 Introduction to Programming I Lecture #06 Recursion Aykut Erdem, Fuat Akal & Aydın Kaya // Fall 2018

Last time Collections, File I/O Lists a = [ 3, 2*2, 10-1 ] b = [ 5, 3, 'hi' ] c = [ 4, 'a', a ] Sets odd = set([1, 3, 5]) prime = set([2, 5]) empty = set([]) Tuples t1 = (1, 'two', 3) t2 = (t1, 3.25) t3 = (t2, t1) Dictionaries c = {"Ankara":"TR","Paris":"FR"} pb = dict() pb["rick"] = "206-555-4455" File I/O myfile = open("output.dat", "w") myfile.write("a bunch of data") myfile.write("a line of text\n") myfile.close() 2

Lecture Overview Notion of state in computation Recursion as a programming concept Mutual recursion Recursion tree Pitfalls of recursion Disclaimer: Much of the material and slides for this lecture were borrowed from E. Grimson, J. Guttag and C. Terman in MITx 6.00.1x, J. DeNero in CS 61A (Berkeley), T. Cortina in 15110 Principles of Computing (CMU) R. Sedgewick, K. Wayne and R. Dondero (Princeton) 3

Recursion Recursion is a programming concept whereby a function invokes itself. Recursion is typically used to solve problems that are decomposable into subproblems which are just like the original problem, but a step closer to being solved. Drawing Hands, by M. C. Escher (lithograph, 1948) 4

Computation All computation consists of chugging along from state to state to state... There is a set of rules that tells us, given the current state, which state to go to next. 5

Arithmetic as Rewrite Rules 2 + 3 + 4 5 + 4 9 Expression evaluation We stop when we reach a number 6

Functions as New Rules def square(n): return n * n When we see: square(something) Rewrite it as: something * something 7

Functions as Rewrite Rules def square(n): return n * n square(3) 3 * 3 9 8

Piecewise Functions f(n) = 1 if n = 1 n - 1 if n > 1 f(4) 4-1 3 9

In Python def f(n): if n == 1: return 1 else: return n - 1 10

This is just math, right? Difference between mathematical functions and computation functions. Computation functions must be effective. For example, we can define the square-root function as x = y such that y 0 and y² = x This defines a valid mathematical function, but it doesn't tell us how to compute the square root of a given number. 11

Fancier Functions def f(n): return n + (n - 1) Find f(4) 12

Fancier Functions def def f(n): return n + (n - 1) g(n): return n + f(n - 1) Find g(4) 13

Fancier Functions def def def f(n): return n + (n - 1) g(n): return n + f(n - 1) h(n): return n + h(n - 1) Find h(4) 14

Recursion def h(n): return n + h(n - 1) h is a recursive function, because it is defined in terms of itself. 15

Definition Recursion See: "Recursion". 16

Recursion def h(n): return n + h(n - 1) h(4) 4 + h(3) 4 + 3 + h(2) 4 + 3 + 2 + h(1) 4 + 3 + 2 + 1 + h(0) 4 + 3 + 2 + 1 + 0 + h(-1) 4 + 3 + 2 + 1 + 0 + -1 + h(-2)... Evaluating h leads to an infinite loop! 17

What you are thinking? "Ok, recursion is bad. What's the big deal?" 18

Recursion def f(n): if n == 1: return 1 else: return f(n - 1) Find f(1) Find f(2) Find f(3) Find f(100) 19

Recursion def f(n): if n == 1: return 1 else: return f(n - 1) f(3) f(3-1) f(2) f(2-1) f(1) 1 20

Terminology def f(n): if n == 1: return 1 else: return f(n - 1) base case recursive case "Useful" recursive functions have: at least one recursive case at least one base case so that the computation terminates 21

Recursion def f(n): if n == 1: return 1 else: return f(n + 1) Find f(5) We have a base case and a recursive case. What's wrong? The recursive case should call the function on a simpler input, bringing us closer and closer to the base case. 22

Recursion def f(n): if n == 0: return 0 else: return 1 + f(n - 1) Find f(0) Find f(1) Find f(2) Find f(100) 23

Recursion def f(n): if n == 0: return 0 else: return 1 + f(n - 1) f(3) 1 + f(2) 1 + 1 + f(1) 1 + 1 + 1 + f(0) 1 + 1 + 1 + 0 3 24

Iterative algorithms Looping constructs (e.g. while or for loops) lead naturally to iterative algorithms Can conceptualize as capturing computation in a set of state variables which update on each iteration through the loop 25

Iterative multiplication by successive additions Imagine we want to perform multiplication by successive additions: To multiply a by b, add a to itself b times State variables: i iteration number; starts at b result current value of computation; starts at 0 Update rules i i -1; stop when 0 result result + a 26

Multiplication by successive additions def itermul(a, b): result = 0 while b > 0: result += a b -= 1 return result 27

Recursive version An alternative is to think of this computation as: a * b = a + a +... + a ) ) b)copies) b = a + a +... + a ) b-1 b)copies) copies = a + a * (b 1) 28

Recursion This is an instance of a recursive algorithm Reduce a problem to a simpler (or smaller) version of the same problem, plus some simple computations [Recursive step] Keep reducing until reach a simple case that can be solved directly [Base case] a*b=a; if b=1 (Base case) a * b = a + a * (b-1); otherwise (Recursive case) 29

Recursive Multiplication def recurmul(a,b): if b == 1: return a else: return a + recurmul(a,b-1) 30

Let s try it out def recurmul(a,b): if b == 1: else: return a return a + recurmul(a,b-1) recurmul& Procedure4& &&(a,&b)& &&&if&b&==&1:& &&&&&&&return&a& &&&else:& &&&&&&&return&a&+& recurmul(a,&b=1)& 31

Let s try it out def recurmul(a,b): if b == 1: else: return a recurmul(2,3) return a + recurmul(a,b-1) recurmul& a& 2& b& 3& Procedure4& &&(a,&b)& &&&if&b&==&1:& &&&&&&&return&a& &&&else:& &&&&&&&return&a&+& recurmul(a,&b=1)& 32

Let s try it out def recurmul(a,b): if b == 1: else: return a return a + recurmul(a,b-1) recurmul& a& 2& b& 3& Procedure4& &&(a,&b)& &&&if&b&==&1:& &&&&&&&return&a& &&&else:& &&&&&&&return&a&+& recurmul(a,&b=1)& recurmul(2,3) a& 2& b& 2& 33

Let s try it out def recurmul(a,b): if b == 1: else: return a return a + recurmul(a,b-1) recurmul& a& 2& b& 3& Procedure4& &&(a,&b)& &&&if&b&==&1:& &&&&&&&return&a& &&&else:& &&&&&&&return&a&+& recurmul(a,&b=1)& recurmul(2,3) a& 2& b& 2& a& 2& b& 1& 34

Let s try it out def recurmul(a,b): if b == 1: else: return a return a + recurmul(a,b-1) recurmul& a& 2& b& 3& 6& Procedure4& &&(a,&b)& &&&if&b&==&1:& &&&&&&&return&a& &&&else:& &&&&&&&return&a&+& recurmul(a,&b=1)& recurmul(2,3) a& 2& 4& b& 2& a& 2& b& 1& 2& 35

The Anatomy of a Recursive Function The def statement header is similar to other functions Conditional statements check for base cases Base cases are evaluated without recursive calls Recursive cases are evaluated with recursive calls def recurmul(a,b): if b == 1: return a else: return a + recurmul(a,b-1) 36

Inductive Reasoning How do we know that our recursive code will work? itermul terminates because b is initially positive, and decrease by 1 each time around loop; thus must eventually become less than 1 recurmul called with b = 1 has no recursive call and stops recurmul called with b > 1 makes a recursive call with a smaller version of b; must eventually reach call with b = 1 37

Mathematical Induction To prove a statement indexed on integers is true for all values of n: Prove it is true when n is smallest value (e.g. n = 0 or n = 1) Then prove that if it is true for an arbitrary value of n, one can show that it must be true for n+1 38

Example 0+1+2+3+...+n=(n(n+1))/2 Proof If n = 0, then LHS is 0 and RHS is 0*1/2 = 0, so true Assume true for some k, then need to show that 0 + 1 + 2 +... + k + (k+1) = ((k+1)(k+2))/2 LHS is k(k+1)/2 + (k+1) by assumption that property holds for problem of size k This becomes, by algebra, ((k+1)(k+2))/2 Hence expression holds for all n >= 0 39

What does this have to do with code? Same logic applies def recurmul(a, b): if b == 1: return a else: return a + recurmul(a, b-1) Base case, we can show that recurmul must return correct answer For recursive case, we can assume that recurmul correctly returns an answer for problems of size smaller than b, then by the addition step, it must also return a correct answer for problem of size b Thus by induction, code correctly returns answer 40

Sum digits of a number def split(n): """Split positive n into all but its last digit and its last digit.""" return n // 10, n % 10 def sum_digits(n): """Return the sum of the digits of positive integer n.""" if n < 10: return n else: all_but_last, last = split(n) return sum_digits(all_but_last) + last Verify the correctness of this recursive definition. 41

Some Observations Each recursive call to a function creates its own environment, with local scoping of variables Bindings for variable in each frame distinct, and not changed by recursive call Flow of control will pass back to earlier frame once function call returns value 42

The classic Recursive Problem Factorial n! = n * (n-1) *... * 1 = 1 if n = 0 ) n * (n-1)! otherwise 43

Recursion in Environment Diagrams 44

Recursion in Environment Diagrams (Demo) 45

Recursion in Environment Diagrams (Demo) The same function fact is called multiple times 46

Recursion in Environment Diagrams (Demo) The same function fact is called multiple times Different frames keep track of the different arguments in each call 47

Recursion in Environment Diagrams (Demo) The same function fact is called multiple times Different frames keep track of the different arguments in each call What n evaluates to depends upon the current environment 48

Recursion in Environment Diagrams (Demo) The same function fact is called multiple times Different frames keep track of the different arguments in each call What n evaluates to depends upon the current environment Each call to fact solves a simpler problem than the last: smaller n 49

Iteration vs Recursion 4! = 4 3 2 1 = 24 50

Iteration vs Recursion 4! = 4 3 2 1 = 24 Using while: def fact_iter(n): total, k = 1, 1 while k <= n: total, k = total*k, k+1 return total Math: n! = ny k k=1 Names: n, total, k, fact_iter 51

Iteration vs Recursion 4! = 4 3 2 1 = 24 Using while: Using recursion: def fact_iter(n): total, k = 1, 1 while k <= n: total, k = total*k, k+1 return total def fact(n): if n == 0: return 1 else: return n * fact(n-1) Math: n! = ny k n! = k=1 ( 1 if n =0 n (n 1)! otherwise Names: n, total, k, fact_iter n, fact 52

Recursion on Non-numerics How could we check whether a string of characters is a palindrome, i.e., reads the same forwards and backwards "Able was I ere I saw Elba" attributed to Napolean "Are we not drawn onward, we few, drawn onward to new era? "Ey Edip Adana da pide ye" 53

How to we solve this recursive? First, convert the string to just characters, by stripping out punctuation, and converting upper case to lower case Then a string of length 0 or 1 is a palindrome [Base case] If first character matches last character, then is a palindrome if middle section is a palindrome [Recursive case] 54

Example "Able was I ere I saw Elba" à "ablewasiereisawelba ispalindrome("ablewasiereisawelba") is same as "a"=="a" and ispalindrome("blewasiereisawleb") 55

Palindrome or not? def tochars(s): s = s.lower() ans = '' for c in s: if c in 'abcdefghijklmnopqrstuvwxyz': ans = ans + c return ans 56

Palindrome or not? def ispal(s): if len(s) <= 1: return True else: return s[0] == s[-1] and ispal(s[1:-1]) def ispalindrome(s): return ispal(tochars(s)) 57

Divide and Conquer This is an example of a divide and conquer algorithm Solve a hard problem by breaking it into a set of sub-problems such that: Sub-problems are easier to solve than the original Solutions of the sub-problems can be combined to solve the original 58

Global Variables Suppose we wanted to count the number of times fac calls itself recursively Can do this using a global variable So far, all functions communicate with their environment through their parameters and return values But, (though a bit dangerous), can declare a variable to be global means name is defined at the outermost scope of the program, rather than scope of function in which appears 59

Example def facmetered(n): global numcalls numcalls += 1 if n == 0: return 1 else: return n * facmetered(n-1) def testfac(n): for i in range(n+1): global numcalls numcalls = 0 print('fac of ' + str(i) + ' = ' + str(facmetered(i))) print('fac called ' + str(numcalls) + ' times') testfac(4) 60

Global Variables Use with care!! Destroy locality of code Since can be modified or read in a wide range of places, can be easy to break locality and introduce bugs!! 61

Mutual Recursion Mutual recursion is a form of recursion where two functions or data types are defined in terms of each other. 62

Mutual Recursion Example def even(n): if n == 0: return True else: return odd(n - 1) def odd(n): if n == 0: return False else: return even(n - 1) even(4) 63

The Luhn Algorithm A simple checksum formula used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers, etc. 64

The Luhn Algorithm From Wikipedia: http://en.wikipedia.org/wiki/luhn_algorithm First: From the rightmost digit, which is the check digit, moving left, double the value of every second digit; if product of this doubling operation is greater than 9 (e.g., 7 * 2 = 14), then sum the digits of the products (e.g., 10: 1 + 0 = 1, 14: 1 + 4 = 5) Second: Take the sum of all the digits 1 3 8 7 4 3 2 3 1+6=7 7 8 3 = 30 The Luhn sum of a valid credit card number is a multiple of 10 65

The Luhn Algorithm def luhn_sum(n): """Return the digit sum of n computed by the Luhn algorithm""" if n < 10: return n else: all_but_last, last = split(n) return luhn_sum_double(all_but_last) + last def luhn_sum_double(n): """Return the Luhn sum of n, doubling the last digit.""" all_but_last, last = split(n) luhn_digit = sum_digits(2 * last) if n < 10: return luhn_digit else: return luhn_sum(all_but_last) + luhn_digit 66

Tree Recursion Tree-shaped processes arise whenever executing the body of a recursive function makes more than one recursive call. 67

Tree Recursion Fibonacci numbers Leonardo of Pisa (aka Fibonacci) modeled the following challenge Newborn pair of rabbits (one female, one male) are put in a pen Rabbits mate at age of one month Rabbits have a one month gestation period Assume rabbits never die, that female always produces one new pair (one male, one female) every month from its second month on. How many female rabbits are there at the end of one year? 68

Fibonacci After one month (call it 0) 1 female After second month still 1 female (now pregnant) After third month two females, one pregnant, one not In general, females(n) = females(n-1) + females(n-2) Every female alive at month n-2 will produce one female in month n; These can be added those alive in month n-1 to get total alive in month n Month* Females* 0* 1* 1* 1* 2* 2* 3* 3* 4* 5* 5* 8* 6* 13* 69

Fibonacci Base cases: Females(0) = 1 Females(1) = 1 Recursive case Females(n) = Females(n-1) + Females(n-2) 70

Fibonacci def fib(n): """assumes n an int >= 0 returns Fibonacci of n""" assert type(n) == int and n >= 0 if n == 0: return 1 elif n == 1: return 1 else: return fib(n-2) + fib(n-1) 71

Tiling Squares Rewrite rule: Add square to long side. 72

Tiling Squares What is the side length of each square? 73

Tiling Squares 3 5 1 1 2 8 21 13 74

Spiral 75

Fibonacci 1 1 = 1 2 1 = 2 3 2 = 1.5 5 3 = 1.666... 8 5 = 1.6 13 8 = 1.625 21 13= 1.615... 34 21= 1.619... 76

Limit What is the limit of as n approaches infinity? fib(n) fib(n - 1) 1.6180339887498948482... What's that called? 77

The Golden Ratio The proportions of a rectangle that, when a square is added to it results in a rectangle with the same proportions. + Square = Square 78

The Golden Ratio φ φ 1 = 1 φ - 1 φ 2 - φ - 1 = 0 Square 1 φ = 1 + 5 2 φ-1 = 1.618... 79

Fibonacci fib(n) = 1 n = 1, 2 fib(n-1) + fib(n-2) n > 2 fib(n) = φ n - (1 - φ) n 5 80

Recursion Tree The computational process of fib evolves into a tree structure 81

Recursion Tree The computational process of fib evolves into a tree structure fib(5) 82

Recursion Tree The computational process of fib evolves into a tree structure fib(5) fib(3) 83

Recursion Tree The computational process of fib evolves into a tree structure fib(5) fib(3) fib(4) 84

Recursion Tree The computational process of fib evolves into a tree structure fib(5) fib(3) fib(4) fib(1) fib(2) 1 fib(0) fib(1) fib(2) fib(3) 0 1 fib(0) fib(1) fib(1) fib(2) 0 1 1 fib(0) fib(1) 0 1 85

Recursion Tree The computational process of fib evolves into a tree structure fib(5) fib(3) fib(4) fib(1) fib(2) 1 fib(0) fib(1) fib(2) fib(3) 0 1 fib(0) fib(1) fib(1) fib(2) 0 1 1 fib(0) fib(1) 0 1 86

Recursion Tree The computational process of fib evolves into a tree structure fib(5) fib(3) fib(4) fib(1) fib(2) 1 fib(0) fib(1) fib(2) fib(3) 0 1 fib(0) fib(1) fib(1) fib(2) 0 1 1 fib(0) fib(1) 0 1 87

Recursion Tree The computational process of fib evolves into a tree structure fib(5) fib(3) fib(4) fib(1) fib(2) 1 fib(0) fib(1) fib(2) fib(3) 0 1 fib(0) fib(1) fib(1) fib(2) fib(5) 1 time 0 1 1 fib(0) fib(1) fib(4) fib(3) fib(2) 1 time 2 times 3 times 0 1 88

Pitfalls of Recursion With recursion, you can compose compact and elegant programs that fail spectacularly at runtime. Missing base case No guarentee of convergence Excessive space requirements Excessive recomputation 89

Missing base case def H(n): return H(n-1) + 1.0/n; This recursive function is supposed to compute Harmonic numbers, but is missing a base case. If you call this function, it will repeatedly call itself and never return. 90

No guarantee of convergence def H(n): if n == 1: return 1.0 return H(n) + 1.0/n This recursive function will go into an infinite recursive loop if it is invoked with an argument n having any value other than 1. Another common problem is to include within a recursive function a recursive call to solve a subproblem that is not smaller. 91

Excessive space requirements Python needs to keep track of each recursive call to implement the function abstraction as expected. If a function calls itself recursively an excessive number of times before returning, the space required by Python for this task may be prohibitive. def H(n): if n == 0: return 0.0 return H(n-1) + 1.0/n This recursive function correctly computes the nth harmonic number. However, we cannot use it for large n because the recursive depth is proportional to n, and this creates a StackOverflowError. 92

Excessive recomputation A simple recursive program might require exponential time (unnecessarily), due to excessive recomputation. For example, fib is called on the same argument multiple times fib(5) fib(3) fib(4) fib(1) fib(2) 1 fib(0) fib(1) fib(2) fib(3) 0 1 fib(0) fib(1) fib(1) fib(2) 0 1 1 fib(0) fib(1) 0 1 93

Recursive Graphics Simple recursive drawing schemes can lead to pictures that are remarkably intricate Fractals For example, an H-tree of order n is defined as follows: The base case is null for n = 0. The reduction step is to draw, within the unit square three lines in the shape of the letter H four H-trees of order n-1. One connected to each tip of the H with the additional provisos that the H-trees of order n-1 are centered in the four quadrants of the square, halved in size. 94

More recursive graphics Sierpinski triangles Recursive trees 95