cs 180 programming i aditya p. mathur department of computer sciences purdue university march 29-31,...
Post on 20-Dec-2015
216 views
TRANSCRIPT
CS 180 Programming I
Aditya P. MathurDepartment of Computer SciencesPurdue UniversityMarch 29-31, 2004
Last update: March 30, 2004
Recursion
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 2 of 59
Learning Objectives
How to use recursion for solving problems?
How do recursive programs work?
What is recursion?
Recursion versus iteration
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 3 of 59
What is Recursion?
It is independent of programming language used. You can use recursion in Java, C, C++, or almost any of the well known languages.
A program that uses recursion is known as a recursive program.
We will learn how to code recursive solutions in Java.
A technique for solving problems.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 4 of 59
Iterative solutions: Summation
Problem: Given n integers, find their sum.
Iterative solution: a1, a2, … an
sum=0
sum=0+a1
sum=0+a1+a2
sum=0+a1+a2+…an
.
.
.
sum=0;for(int i=1; i<=n; i++){
sum=sum+a[i];}
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 5 of 59
Iterative solutions: Factorial
Problem: Given n>0, find !n (factorial of n).
Iterative solution: product=1
product=1*2
product=1*2*3
product=1*2*3…*n
.
.
.
product=1;for(int i=2; i<=n; i++){
product=product*i;}
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 6 of 59
Iterative solutions: Fibonacci Series
Problem: Given n>=0, find Fibonacci(n).
Definition: Fib(0)=0; Fib(1)=1; n>1, Fib(n)=Fib(n-1)+Fib(n-2)
Fibonacci series: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55....
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 7 of 59
Iterative solutions: Fibonacci Series
public int fibonacci(int n) { int fib, fibPrev, fibPrevPrev; if (n==0) return(0); if (n==1) return(1); fibPrevPrev=0; fibPrev=1; fib=fibPrev+fibPrevPrev; for (int i=2; i<=n; i++) { System.out.println("Fib("+i+")="+fib); fibPrevPrev=fibPrev; fibPrev=fib; fib=fibPrev+fibPrevPrev; } return(fib); }
fib=0
fib=1
fib=0+1
fib=0+1+1+2+3+5....
.
.
.
fib=0+1+1
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 8 of 59
Recursive solutions: Background: What is tree?
17
12 29
18 32
30 45
Root node
Leaf nodes Internal nodes
Parent nodeChild node
We will see that it is easy to understand how recursionworks with the help of a tree.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 9 of 59
Recursive solutions: Summation
Problem: Given n integers, find their sum.
Recursive solution:(a1+ a2+ … +an)
a1+ (a2+ … +an)
a2+ (a3+ … +an)
a3+ (a4+....+an)...
a(n-1)+ (an)
(a(n-1)+an)
winding phaseunwinding phase
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 10 of 59
Recursive solutions: Summation
Problem: Given n integers, find their sum.
Recursive solution:
(2+3+4)public int sum(int []A, int low, int high){
if(low= =high)return(A[low]);if(low<high)
{ return(A[low]+sum(A,low+1,high));
}}
2+ (3+4)
3+ (4)
=7
=9
Recursive callDo you see any loop here?
=4
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 11 of 59
Recursive solutions: Factorial
Problem: Given n>0, find !n (factorial of n).
Recursive solution:
public int fact(int n){ if (n= =0|| n= =1) return(1); return(n*fact(n-1));}
!4
4* !3
3* !2
=6
=24
2* !1
=2
=1
Recursive call
Again, no loop!
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 12 of 59
Recursive solutions: Fibonacci Series
Problem: Given n>=0, find Fibonacci(n).
Definition: Fib(0)=0; Fib(1)=1; Fib(n)=Fib(n-1)+Fib(n-2)
public int fib(int n) { if (n= =0 ) return(0); if (n= =1 ) return(1); return(fib(n-2)+fib(n-1)); }
fib(4)
fib(2)+ fib(3)
fib(1)+ fib(2)
=3
fib(0)+ fib(1)
fib(0)+ fib(1)
=2
=1
=1
=1
=0
=1
=0 =1
Fibonacci series: 0, 1, 1, 2, 3, 5....Recursive calls
Once again, no loop!
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 13 of 59
Developing a recursive solution: Base case
Step 1: Identify a base case.
This is the case where the solution is derived without recursion.
In most cases it is a simple solution.
The winding phase terminates when the base case is encountered; unwinding begins.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 14 of 59
Base case: Examples
Summation: (a1+a2+...an) , low=1, high=n
For n=1, sum(A, low, high)=alow
Factorial: n=0 !n=1 n=1 !n=1
Fibonacci: n=0 fib(0)=0 n=1 fib(1)=1
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 15 of 59
Recursive case
Step 2: Identify the recursive, or the general, case.
This is the case where the solution is derived by invoking the same method recursively until a base case encountered.
A recursive call continues the winding phase.
Did you notice the Divide and Conquer strategyin our examples?
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 16 of 59
Recursive case: Examples
Summation: For n>1, low=1, high=n. (low<high), sum(A, low, high)=alow+sum(A, low+1, high)
Factorial: For n>1, fact(n)=n*fact(n-1)
Fibonacci: For n>1, fib(n)=fin(n-2)+fib(n-1)
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 17 of 59
Recursive and base cases: summary
Summation:
A=(a1, a2,...an), n>0, low=1, high=n low=high, sum(A, low, high)=alow low<high, sum(A, low, high)=alow+sum(A, low+1, high)
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 18 of 59
Recursive and base cases: summary
Factorial: n=0, !n=1 n=1, !n=1 n>1, fact(n)=n*fact(n-1)
Fibonacci: n=0, fib(n)=0 n=1, fib(n)=1
n>1, fib(n)=fin(n-2)+fib(n-1)
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 19 of 59
Loops and recursion
In fact a program may use recursion and iteration and hence will be composed of loops as well as recursive calls.
In our examples, there was no loop (e.g. while-do, for).
This does not imply that programs with recursion are free of loops created using while-do, for, etc.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 20 of 59
Difficulty in writing a recursive program
Some find it difficult to write a recursive program than to write an iterative program.
The difficulty arises in identifying the base and the recursive cases.
In most problems, it is easy to identify the base case. The difficulty lies in identifying the recursive , or the “general” case.
Suggestion: Focus on identifying the base and general cases beforeyou start writing a recursive program.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 21 of 59
Recursion and “lazy evaluation”
Note that in our examples, the intermediate solutions are “postponed.”
Thus to find (2+3+4) we first added 3 to 4 and then added 2 to the sum.
Similarly, to find !4, we first found !3 and then multiplied it by 4. To find !3 we found !2 and multiplied it by 3. To find !2 we found !1 and multiplied it by 2. !1 is a base case.
This strategy of postponing the application of operationsis also known as “lazy evaluation.”
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 22 of 59
“lazy evaluation” requires memory
In each of our three examples, when we make a recursive call, we postponed a computation.
For example to find !4, we first found !3 but remembered that !3 is to be multiplied by 4 to get !4. Similarly, to find !3, we remembered (a) 3 is to be multiplied by !2 to get !3 and (b) that 4 is to be multiplied by !3.
Java does this “remembering” for us automatically by using a stack.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 23 of 59
Stack
Upon each recursive call, Java interpreter pushes, whatever is to be remembered, on a stack.
The stack “grows” in the winding phase as more and more data is added to it.
During the unwinding phase, Java interpreter removes data rom the top of the stack and performs the desired operation.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 24 of 59
Quiz (March 29, 2004)
What is Fibonacci(6)?
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 25 of 59
Stack Example: Summation: Winding
(2+3+4)
Data stack empty before sum( ) is calledlow=1, high=3
2 pushed on the stackright before the first recursive call.low=2, high=3
2
(2+(3+4))
3 pushed on the stackright before the second recursive call. low=3, high=3
2
3
(2+(3+(4)))
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 26 of 59
Stack Example: Summation: Unwind
(2+(3+4))
4 pushed on the stackright after return from the last call
2
3
4
4+3 pushed on the stackright after another return.
2
7
(2+7)
9 pushed on the stackright after return to mainmain gets the result from the stack.
(9)
9
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 27 of 59
Iteration versus recursion
Recursion is often more expensive than iteration in terms of execution time and stack memory required.
For some problems recursion offers an easy and natural solution. Iterative solutions might be difficult and unnatural.
Four examples follow: Towers of Hanoi Merge sort Tree traversal Shortest distance between two cities.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 28 of 59
Danger!
If your base case is incorrect, or coded incorrectly, you might end up with a program that has infinite recursion!
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 29 of 59
Towers of Hanoi
Source Peg (A) Intermediate Peg (B) Destination Peg (C)
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 30 of 59
Towers of Hanoi: The Problem
Source Peg (A) has N disks stacked vertically in the order of their size as shown. (N>0).
The problem is find the shortest sequence of moves that will transfer all N disks from the Source Peg (A) to the Destination Peg (C).
The Intermediate Peg (B) can be used for temporary placement of disks.
A larger disk should NEVER be placed on top of a smaller disk.
Only one Disk can be moved from the top of one Peg and placed on top of another peg in one move.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 31 of 59
Towers of Hanoi: Base and Recursive Cases
Base case: N=1
Solution: moveDisk (A, C). This moves one disk from A to C.
Recursive case: N>1
Solution: moveDisks(N-1, A, B, C): Move N-1 disks from A to B via C.moveDisk(A, C): This moves one disk from A to C. moveDisks(N-1, B, C, A): Move N-1 disks from B to C via A.
from to via
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 32 of 59
Towers of Hanoi: Recursive case
Source Peg (A) Intermediate Peg (B) Destination Peg (C)
moveDisks(N-1, A, B, C): Move N-1 disks from A to B via C.moveDisk(A, C): This moves one disk from A to C. moveDisks(N-1, B, C, A): Move N-1 disks from B to C via A.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 33 of 59
Towers of Hanoi: Recursive case
Source Peg (A) Intermediate Peg (B) Destination Peg (C)
moveDisks(N-1, A, B, C): Move N-1 disks from A to B via C.moveDisk(A, C): This moves one disk from A to C. moveDisks(N-1, B, C, A): Move N-1 disks from B to C via A.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 34 of 59
Towers of Hanoi: Recursive case
Source Peg (A) Intermediate Peg (B) Destination Peg (C)
. moveDisks(N-1, A, B, C): Move N-1 disks from A to B via C.moveDisk(A, C): This moves one disk from A to C. moveDisks(N-1, B, C, A): Move N-1 disks from B to C via A.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 35 of 59
Towers of Hanoi: A Java Program
private void moveDisk(String from, String to) { System.out.println(“Move disk from:"+ from+" to: "+to); }
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 36 of 59
Towers of Hanoi: A Java Program
private void moveDisks(int disks, String from, String to, String intermediate) { if(disks==1) { moveDisk(from, to); } else { moveDisks(disks-1, from, intermediate, to); moveDisk(from, to); moveDisks(disks-1, intermediate, to, from); } }
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 37 of 59
Towers of Hanoi: Sample Execution
moveDisks(3, “A”, “B”, “C”);
Move: 1 Move disk from:Peg A to: Peg CMove: 2 Move disk from:Peg A to: Peg BMove: 3 Move disk from:Peg C to: Peg BMove: 4 Move disk from:Peg A to: Peg CMove: 5 Move disk from:Peg B to: Peg AMove: 6 Move disk from:Peg B to: Peg CMove: 7 Move disk from:Peg A to: Peg C
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 38 of 59
Merge sort
A method for sorting an array of data.
A=[a1 a2 a3...an]
Divide array into two halves: front and tail.
front=[a1 a2...a(n/2)]
tail=[a(n/2) a(n/2+1).....an]
Sort front and tail and merge the two in to A.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 39 of 59
Merge sort: Base and recursive cases
n=1: A is already sorted. Do nothing!
n>1: Divide array into two halves: front and tail.
front=[a1 a2...a(n/2)]
tail=[a(n/2) a(n/2+1).....an]
sort(front) and sort(tail); do this recursively. Merge sorted front and tail into A.
sort(A[]);
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 40 of 59
Merge sort: Illustration
sort([14 2 0 ])
wind unwind
merge([2 14], [0])
[0 2 14]
merge([14],[2])[2 14]sort([14 2]) sort([0])front tail
sort([2])sort([14])
front tail
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 41 of 59
Problem: Tree traversal: Infix order
17
12 29
18 32
30 45
Traverse a binary tree in infix order and print the data in its nodes.
Infix order
Traverse the left subtree, print root, traverse the right subtree.
Infix order: 12, 17, 18, 29, 30, 32, 45
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 42 of 59
Problem: Tree traversal: Prefix order
*
a +
b /
c d
Traverse a binary tree in prefix order and print the data in its nodes.
Prefix order
Print root, traverse the left subtree, traverse the right subtree.
Prefix order: *a(+b(/cd))
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 43 of 59
Problem: Tree traversal: Postfix order
*
a +
b /
c d
Traverse a binary tree in prefix order and print the data in its nodes.
Postfix order
Traverse the left subtree, traverse the right subtree, print root.
Postfix order: a b c d / + *
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 44 of 59
Problem: Tree traversal: Infix order
Write a Java program to traverse a binary tree in infix order and print the data in its nodes.
17
12 29
18 32
30 45
head
Node
leftlink
data rightlink
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 45 of 59
Problem: Tree traversal: Base and Recursive Cases
Base case: head=nullOutput: None
Recursive case: head!=nullOutput:
traverse(head.leftLink( ))print head.data( )traverse(head.rightLink( ))
17
12 29
18 32
30 45
head
156
6 17 18 29 30 32 451512
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 46 of 59
Shortest Path: The Problem
We are given a network of cities and links (roads) that connect them.
Links are assumed to be directional and have distances associated with them.
Given two cities C1 and C2 find the shortest path from C1 to C2 in terms of the distance if a path exists otherwise notify that there is no such path.
shortestPath(C1, C2) returns Path. A Path has path which is a non-empty string of cities and a distance, if it exists. Else the path is an empty string.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 47 of 59
Shortest Path: The Network
1
4
5
2
3
650
50
12040
80
130
70
45
60 70
shortestPath(1, 6): path: 1-->4-->6 distance=120shortestPath(3, 6): path: “” distance=undefined
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 48 of 59
Base case:
Base Case 1:There are one or more direct links from C1 to C2.
Solution:
Find link with the shortest distance.
shortestPath(1,2): Path: 1-->2. Distance: 50.
12
60
50
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 49 of 59
Base case:
Base Case 2:There are no outgoing links from C1.
Solution:
Path does not exist.
3
shortestPath(3, 6): Path: “” distance: undefined.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 50 of 59
Base case:
Base Case 3:C1 and C2 are the same
Solution:
shortestPath(4, 4): Path: “4-->4” distance: 0.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 51 of 59
Recursive case
There is no direct link from C1 to C2.
if (count==0) then return(“”);else
return(paths[j]) such that paths[j].distance() is the smallest amongst all elements of paths[];
Solution:
count=0;
for (each outgoing link from C1)
{ Path p=shortestPath(tail(link), C2);
if(p!=“”)paths[count++]=addPaths((link(C1, C2), p);}
12
60
50
440
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 52 of 59
Recursive case: Examine links from 1
shortestPath(1, 6): There is no direct link from 1 to 6. Hence we find shortestPath(2, 6), shortestPath(2, 6), and shortestPath(4, 6) corresponding to the three outgoing links from 1.
1
4
5
2
3
650
50
12040
80
130
70
45
60 70
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 53 of 59
Recursive case: Examine links from 2
shortestPath(2, 6): There is no direct link from 2 to 6. Hence we find shortestPath(3, 6) corresponding to the lone outgoing link from 2.
1
4
5
2
3
650
50
12040
80
130
70
45
60 70
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 54 of 59
Recursive case: Examine links from 3
shortestPath(3, 6): There is no link from 3 and hence return empty path (implying that no path was found) This also happens for the other link from 1 to 2 (with distance=60).
130
1
4
5
2
3
650
50
12040
80
70
45
60 70
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 55 of 59
Recursive case: Examine links from 4
shortestPath(4, 6): There is a direct link from 4 to 6 and hence return path with string “4-->6” and distance=80. shortstPath(3, 6) returns an empty path.
1
4
5
2
3
650
50
12040
80
130
70
45
60 70
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 56 of 59
Recursive case: Get back to 1
append(link(1, 4), shortestPath(4,6)): We get the path “1-->4-->6” and a distance of 120. Done!
1
4
5
2
3
650
50
12040
80
130
70
45
60 70
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 57 of 59
Issues (Been to MapQuest?)
How does one handle cycles?
1
4
5
2
3
650
50
12040
80
130
70
45
60 70
How to handle bi-directional links?...etc. etc.
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 58 of 59
Quiz (March 31, 2004)
Saturn
Jupiter Neptune
Uranus Earth
head
In what order will the planets in the following tree be listed if the tree is traversed in infix order?
Recursion: CS 180 Spring 2004 Aditya P. Mathur 2004 59 of 59
Bye!
Have funwith
Recursion!