Programming Appreciation Camp. Session 2: Recursion Steven Halim NUS School of Computing. Recap. In the first session, we have learnt/done some problem solving using algorithm: Algorithms have three control structures: Sequence Selection (branching) Repetition (loop) And Recursion.
Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.
Programming Appreciation Camp
Session 2: Recursion
Steven Halim
NUS School of Computing
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
http://en.wikipedia.org/wiki/Matryoshka_doll
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
The answer for this scenario: 5 lakes!
[Programming Appreciation Camp November 2008]
numOfW 0for each cell(i,j) in the map // (0,0) to (9,9) if (cell(i,j) is character ‘W’) numOfW numOfW + 1printf numOfW // W = 18 in this case
A=10, B=11, …, I = 18
So, how to answer: 5 lakes?
Use recursion!
This problem will be revisitedat the latter part of this session!
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
Recursive_Function_Name(Parameter_List)
// you will always see “selection statement” (if, switch, etc)
if (base_case) // problem is trivial, there can be more than one
do_something_simple // produce the result directly
else // recursive case
// Simplify the problem and then call this same function again
Recursive_Function_Name(Modified_Parameter_List)
[Programming Appreciation Camp November 2008]
7 recursion examples to get you started
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
count_down(n) if (n <= 0) print “BLAST OFF!!!!” else print “Time = ” + ncount_down(n-1)
Base Case
occurs when n <= 0
If this happens, simply print “BLAST OFF!!!!”
Recursive Case
occurs when n > 0
If this happens, print the current time,
and then call a simpler problem:
count_down(n-1)
Note that this recursive function returns nothing
[Programming Appreciation Camp November 2008]
count_down(n) if (n <= 0) print “BLAST OFF!!!!” else print “Time = ” + ncount_down(n-1)
count_down(3) Time = 3Time = 2Time = 1BLAST OFF!!!!
count_down_itr(n) for (t=n to 0, decrement by 1) print “Time = ” + t print BLAST OFF!!!!”// actually the iterative// version is simpler// for this case
count_down_itr(3) Time = 3Time = 2Time = 1BLAST OFF!!!!
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
fact(n) if (n = 0) return 1 else return n * fact(n-1)
Base Case
occurs when n = 0
If this happens, simply return 1, 0! = 1
Recursive Case
occurs when n > 0
If this happens, return n * result of simpler problem of fact(n-1)
Note that this recursive function returns a number, which is the result of fact(n)
[Programming Appreciation Camp November 2008]
fact(n) if (n = 0) return 1 else return n * fact(n-1)
fact(0) 1 (base case)fact(1) 1*fact(0) = 1*1 = 1fact(2) 2*fact(1) = 2*1 = 2fact(3) 3*fact(2) = 3*2 = 6fact(4) 4*fact(3) = 4*6 = 24fact(5) 5*fact(4) = 5*24 = 120…see visual explanation
[Programming Appreciation Camp November 2008]
fact(n) if (n = 0) return 1 else return n * fact(n-1)
fact(0) 1 (base case)fact(1) 1*fact(0) = 1*1 = 1fact(2) 2*fact(1) = 2*1 = 2fact(3) 3*fact(2) = 3*2 = 6fact(4) 4*fact(3) = 4*6 = 24fact(5) 5*fact(4) = 5*24 = 120…
fact_itr(n) { result 1 for (i=1 to n, increment by 1) result result * i return result
fact_itr(0) 1fact_itr (1) 1fact_itr (2) 1*2 = 2fact_itr (3) 1*2*3 = 6fact_itr (4) 1*2*3*4 = 24fact_itr (5) 1*2*3*4*5 = 120…
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
fib(n) if (n <= 1) // for 0 and 1 return n else return fib(n-1) + fib(n-2)
Base Case
occurs when n <= 1 (0 or 1 only)
If this happens, simply return n (the value itself)
Recursive Case
occurs when n > 1
If this happens, return fib(n-1) + fib(n-2)
we call the same function twice!
Here, we observe that a recursive function can call itself more than once! (branching recursion)
[Programming Appreciation Camp November 2008]
fib(n) if (n <= 1) // for 0 and 1 return n else return fib(n-1) + fib(n-2)
fib(0) 0 (base case)fib(1) 1 (base case) fib(2) fib(0)+fib(1) = 0+1 = 1fib(3) fib(1)+fib(2) = 1+1 = 2fib(4) fib(2)+fib(3) = 1+2 = 3fib(5) fib(3)+fib(4) = 2+3 = 5…
fib[0] 0fib[1] 1for (i=2 to n, increment by 1) fib[i] fib[i-1] + fib[i-2]
fib[0] = 0fib[1] = 1fib[2] = 1fib[3] = 2fib[4] = 3fib[5] = 5…
[Programming Appreciation Camp November 2008]
On my machine
fib(20) ~ 0.0 second fib(30) ~ 0.0 secondfib(35) ~ 1 secondfib(36) ~ 2 secondsfib(37) ~ 4 secondsfib(38) ~ 6 secondsfib(39) ~ 8 seconds fib(40) ~ 11 seconds
On my machine
fib(20) ~ 0.0 second fib(30) ~ 0.0 secondfib(35) ~ 0.0 second fib(36) ~ 0.0 second fib(37) ~ 0.0 second fib(38) ~ 0.0 second fib(39) ~ 0.0 second fib(40) ~ 0.0 second
[Programming Appreciation Camp November 2008]
Fib 5
Fib 3
Fib 4
Fib 1
Fib2
Fib 2
Fib 3
1
Fib 1
Fib 0
Fib 0
Fib1
Fib 1
Fib 2
1
0
0
1
1
Fib 0
Fib1
0
1
_____________
[Programming Appreciation Camp November 2008]
pow2(n) if (n = 0) return 1 else if (n = 1) return 2 else return 2 * pow2(n-1)
Base Case
occurs when n = 0 or n = 1
there can be >= 1 base case(s)
If this happens, return 1 for 20 or 2 for 21
Recursive Case
occurs when n > 1
If this happens, return 2 * pow2(n-1)
pow2(n-1) is a simplified problem
Here, we observe that a recursive function can have more than one base cases (processed differently)
[Programming Appreciation Camp November 2008]
pow2(n) if (n = 0) return 1 else if (n = 1) return 2 else return 2 * pow2(n-1)
pow2(1) 2 (base case)pow2(2) 2*pow2(1) = 2*2 = 4pow2(3) 2*pow2(2) = 2*4 = 8 pow2(4) 2*pow2(3) = 2*8 = 16 …
pow2_itr(n) result 1 for (i=1 to n, increment by 1) result result * 2 return result
pow2_itr(1) 1*2=2pow2_itr (2) 1*2*2=4pow2_itr (3) 1*2*2*2=8pow2_itr (4) 1*2*2*2*2=16
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
digit(n) if (n > 0) digit(n / 10) print n % 10
Base Case
occurs when n <= 0
If this happens, do nothing!
Recursive Case
occurs when n > 0
If this happens, call print_digit with simplified problem: one less ‘digit’ (n / 10)
then, print n % 10. % is called themodulus (remainder) operator.
Here, we observe that base case can be as simple as doing nothing and we can still do something after recursive calls!
[Programming Appreciation Camp November 2008]
digit(n) if (n > 0) digit(n / 10) print n % 10
digit(2008)
2
0
0
8
Details in the next slide!
digit_itr(n) while (n > 0) print n % 10 n n / 10
digit_itr(2008)
8
0
0
2
* This is not what we want…
* We need to reverse the answer!
[Programming Appreciation Camp November 2008]
digit(n) if (n > 0) digit(n / 10) print n % 10
digit(2008)
2
0
0
8
See diagram for clarity
[Programming Appreciation Camp November 2008]
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
Compute nCk or C(n,k)
nCk = n! / (k! * (n – k)!)
[Programming Appreciation Camp November 2008]
32
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
Recursive version only:
choose(n, k) if (k = 0 or k = n) return 1 else
return choose(n-1,k-1) + choose(n-1,k)
[Programming Appreciation Camp November 2008]
This problem is not intuitive to be solved iteratively!
However, the recursive solution has many similar sub-problems (compare with Fibonacci)
Special:
Closed form:nCk = n!/(k!*(n-k)!)
6 in this case!
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
bsearch(arr, key, low, high) {if (high < low)return -1 // not found, base case 1
mid (low + high) / 2
if (arr[mid] > key)return bsearch(arr, key, low, mid-1) // recursive case 1: leftelse if (arr[mid] < key)return bsearch(arr, key, mid+1, high) // recursive case 2: rightelsereturn mid // found, base case 2
[Programming Appreciation Camp November 2008]
bsearch(A, 7, 0, 3) // mid is 1, A[1] = 7, 7 == 7, found it
return 1; // found in index 1
return 4; // found in index 4
bsearch(A, 82, 5, 9) // mid is 7, A[7] = 73 , 82 > 73, go to right side
bsearch(A, 82, 8, 9) // mid is 8, A[8] = 81, 82 > 81, go to right side
bsearch(A, 82, 9, 9) // mid is 9, A[9] = 99, 82 < 99, go to left side
bsearch(A, 82, 9, 8) // base case, not found
return -1; // not found
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
The answer for this scenario: 5 lakes!
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
floodfill(r, c, ID) if (r < 0 or r > 9 or c < 0 or r > 9) return // base case 1: exceeding boundary if (cell(r,c) is not character ‘W’) return // base case 2: not water cell(r,c) ID // simplify the problem W to ID: 1 ‘W’ less// recursively fill the 4 directions floodfill(r, c+1, ID) // east floodfill(r-1, c, ID) // north floodfill(r, c-1, ID) // west floodfill(r+1, c, ID) // south
floodfill(1,2,‘1’) // fill lake starting from (1,2) with ‘1’
[Programming Appreciation Camp November 2008]
lake 0for each cell(i,j) in the map if (cell(i,j) is character ‘W’)floodfill(i, j, ‘1’+lake) lake lake + 1printf lake // 5 in this case
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
7 more recursion examples that we will discuss together
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]
A word is a palindrome if it reads the same forward and backward
How do you determine if a word is a palindrome?
Recursively!
Sample calls:
Palindrome(“”) = false
Palindrome(“O”) = true
Palindrome(“OO”) = true
Palindrome(“NOON”) = true
Palindrome(“D”) = true
Palindrome(“ADA”) = true
Palindrome(“RADAR”) = true
[Programming Appreciation Camp November 2008]
52
North-east (NE) path: you may only move northward or eastward
Find the number of north-east pathsbetween A and C.
Recursively!
C
A
[Programming Appreciation Camp November 2008]
53
Given this list of coin denominations: $1, 50 cents, 20 cents, 10 cents, 5 cents, 1 cent, find the smallest number of coins needed for a given amount. You do not need to list out what coins are used.
Example 1: For $3.75, 6 coins are needed.
Example 2: For $5.43, 10 coins are needed.
Recursively!
[Programming Appreciation Camp November 2008]
54
[Programming Appreciation Camp November 2008]
[Programming Appreciation Camp November 2008]