Download presentation
Presentation is loading. Please wait.
Published byAlexandra Bakosné Modified over 5 years ago
1
Recursion Recursio Recursi Recurs Recur Recu Rec Re R
2
Methods that call themselves
Consider 5! equates to 5 * 4 * 3 * 2 * 1 This is an iterative example, as is the code: public static long fact(int n) { long prod = 1; for(int i=1; i<=n; i++) prod *= i; return prod; } How would you define n! in an iterative fashion?
3
Methods that call themselves
Consider 5! equates to 5 * 4 * 3 * 2 * 1 This is an iterative example, as is the code: public static long fact(int n) { long prod = 1; for(int i=1; i<=n; i++) prod *= i; return prod; } How would you define n! in an iterative fashion? n! = (n) * (n-1) * (n-2) * (n-3) * … * 3 * 2 * 1
4
n! = (n) * (n-1) * (n-2) * (n-3) * … * 3 * 2 * 1
This is a lousy mathematical definition: It doesn’t work for n==0, 1, 2, 3, 4, 5, or 6 No mathematic definition should contain “…” Consider a definition of n! that is more mathematically sound:
5
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4!
6
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 3!
7
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2!
8
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1!
9
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1! 1! = 1 * 0!
10
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1! 1! = 1 * 0! 0! = 1
11
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1! 1! = 1 * 1 = 1
12
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1 = 2
13
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2 = 6
14
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! 4! = 4 * 6 = 24
15
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 24 = 120
16
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! and 0! = 1 So what is n!...
17
This is a recursive definition:
5! = 5 * (4 * 3 * 2 * 1) Note that 4! = (4 * 3 * 2 * 1) 5! = 5 * 4! and 0! = 1 So what is n!... n! = n * (n-1)! and 0! = 1 This is a recursive definition: We define n-factorial by calling factorial in the next easiest state (recursive call) We tell it when to stop, 0! = 1 (terminating case)
18
the method MUST know when to stop, which is the terminating case.
public static long fact(int n) { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } there is no loop loop-like behavior is achieved by the method calling itself inside of itself the method MUST know when to stop, which is the terminating case.
19
public static long fact(int n) //5 { if( n == 0) //terminating case, 0
public static long fact(int n) //5 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5)
20
public static long fact(int n) //5 { if( n == 0) //terminating case, 0
public static long fact(int n) //5 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4)
21
public static long fact(int n) //4 { if( n == 0) //terminating case, 0
public static long fact(int n) //4 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4)
22
public static long fact(int n) //4 { if( n == 0) //terminating case, 0
public static long fact(int n) //4 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3)
23
public static long fact(int n) //3 { if( n == 0) //terminating case, 0
public static long fact(int n) //3 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3)
24
public static long fact(int n) //3 { if( n == 0) //terminating case, 0
public static long fact(int n) //3 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * fact(2)
25
public static long fact(int n) //2 { if( n == 0) //terminating case, 0
public static long fact(int n) //2 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * fact(2)
26
public static long fact(int n) //2 { if( n == 0) //terminating case, 0
public static long fact(int n) //2 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * fact(2) = 2 * fact(1)
27
public static long fact(int n) //1 { if( n == 0) //terminating case, 0
public static long fact(int n) //1 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * fact(2) = 2 * fact(1)
28
public static long fact(int n) //1 { if( n == 0) //terminating case, 0
public static long fact(int n) //1 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * fact(2) = 2 * fact(1) = 1 * fact(0)
29
public static long fact(int n) //0 { if( n == 0) //terminating case, 0
public static long fact(int n) //0 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * fact(2) = 2 * fact(1) = 1 * fact(0) = 1
30
public static long fact(int n) //1 { if( n == 0) //terminating case, 0
public static long fact(int n) //1 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * fact(2) = 2 * fact(1) = 1 * 1 = 1
31
public static long fact(int n) //2 { if( n == 0) //terminating case, 0
public static long fact(int n) //2 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * fact(2) = 2 * 1 = 2
32
public static long fact(int n) //3 { if( n == 0) //terminating case, 0
public static long fact(int n) //3 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * fact(3) = 3 * 2 = 6
33
public static long fact(int n) //4 { if( n == 0) //terminating case, 0
public static long fact(int n) //4 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * fact(4) = 4 * 6 = 24
34
public static long fact(int n) //5 { if( n == 0) //terminating case, 0
public static long fact(int n) //5 { if( n == 0) //terminating case, 0! = 1 return 1; return n * fact(n – 1); //recursive call, n! = n * (n-1)! } fact(5) = 5 * 24 = 120
35
Recursive thinking First consider the terminating case:
What is the most simple possible input such that the method already knows the answer? For factorial, the easiest number to find the factorial of is zero. fact(0) should return 1. Then, given complex input, what would be considered “one-step-easier”. For factorial, fact(5) would be complex. One-step-easier than fact(5) would be fact(4). Now, how can you define the solution given complex input by calling the method given “one-step-easier”? For factorial, fact(5) is equivalent to 5 * fact(4) Lastly, replace the complex input with the argument name. If fact(5) = 5 * fact(4), then fact(n) = n * fact(n-1)
36
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } Note: terminating case not implicitly stated, but… If n < 0, the if statement is skipped and the method ends. If we keep subracting 2 from n, the condition will eventually be false and the method can stop.
37
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) output
38
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) SOP(6) doStuff(4) output 6
39
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) SOP(6) doStuff(4) output 6
40
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) output 6 4
41
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) output 6 4
42
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) doStuff(0) output 6 4 2
43
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) doStuff(0) output 6 4 2
44
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) doStuff(0) SOP(0) doStuff(-2) output 6 4 2
45
void recursion public static void doStuff(int n) { if(n >= 0) System.out.println(n); doStuff(n – 2); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) doStuff(0) SOP(0) output 6 4 2 doStuff(-2)
46
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) output
47
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) doStuff(4) //we will, in order, call //doStuff(4) and then //print the 6. //But we must finish //doStuff(4) before we //print the 6 SOP(6) output
48
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) output
49
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) doStuff(2) //we will, in order, call //doStuff(2) and then //print the 4. //But we must finish //doStuff(2) before we //print the 4 SOP(4) output
50
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) output
51
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) doStuff(0) //we must finish //doStuff(0) before //we print the 2 SOP(2) output
52
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) doStuff(0) output
53
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) doStuff(0) doStuff(-2) SOP(0) output
54
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) doStuff(0) SOP(0) doStuff(-2) output
55
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) doStuff(0) SOP(0) output
56
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) SOP(4) doStuff(2) SOP(2) output 2
57
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) doStuff(4) SOP(4) output 2 4
58
void - code after recursive call
public static void doStuff(int n) { if(n >= 0) doStuff(n – 2); System.out.println(n); } doStuff(6) SOP(6) output 2 4 6
59
Project 12_1 The book says: gcd(a, b) = b, when a = 0 gcd(a, b) = gcd(b, a % b), when a > 0 It should be: gcd(a, b) = a, when b = 0
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.