10.2 Implementation and Execution of Recursive Code
A recursive definition can be implemented in code in order to calculate the value of a function. That part of the definition where the function is defined in terms of itself is implemented as a method that calls itself. The base case is also a necessary part of the implementation. Both parts will be illustrated in the examples that follow. Recursion in Code
Example of Recursion in Code Shown on the next slide is a complete test program and class containing a static method with recursion that finds the number of balls in a pool rack. All elements of a correct implementation are present in the example. There is a certain redundancy in the use of the variable returnValue and the return statements in the method. The example is written in this way in order to make it easier to pinpoint certain actions in the code in the explanations that follow. In the definitions above, the recursive case was shown first. This emphasized the recursion. In this implementation and those that follow, the base case is checked for first. This is done with an if statement. If the base case has not been reached, then the method calls itself again, which is recursion. Example of Recursion in Code
Example of Recursion in Code, cont. import java.util.Scanner; public class TestPool { public static void main(String[] args) Scanner in = new Scanner(System.in); int myRows, myResult; System.out.print("How many rows of balls? "); myRows = in.nextInt(); myResult = PoolClass.poolRack(myRows); System.out.println("This is the total number of balls: " + myResult); } Example of Recursion in Code, cont.
Example of Recursion in Code, cont. public class PoolClass { public static int poolRack(int numOfRows) int returnValue; if(numOfRows == 1) returnValue = 1; return returnValue; } else returnValue = numOfrows + poolRack(numOfRows – 1); Example of Recursion in Code, cont.
Explanation of Recursion Code Note that the body of the method is structured as an if statement. If the base case has been reached, then a simple value can be returned. If the base case has not been reached, then another call to the method is made. In the call, the value of the parameter is decreased by 1. Successive calls approach, and ultimately reach the value given in the base case, so the recursion will stop successfully. Explanation of Recursion Code
Explanation of Recursion Code, cont. It may not be clear just from looking at the code how recursion works. There is a general technique for understanding code which can be applied to this example. The technique involves tracing the parameter values and return values through a sequence of recursive calls. It is possible to draw a diagram using boxes to represent the calling program and the separate executions of the recursive method. When writing and debugging code, this can be done by hand, noting parameter values and return values in the diagram. Explanation of Recursion Code, cont.
Recursion Diagram Example On the next slide, there is such a diagram for the pool rack method where the calling program sends in an initial parameter value of 3. This diagram was produced by an applet which was designed to animate recursion. The path of execution goes down the left hand side through the sequence of activations of the recursive method, and back up the right hand side as each activation is done and returns a value. Recursion Diagram Example
Recursion Diagram Example, cont.
Recursion Diagram Example, cont. The exact relationship between the different calls may still not be clear. In effect, recursive calls are stacked calls. Each activation of the method runs until it makes a recursive call. It then waits for that call to return a value before continuing to completion. In the diagram, main() and two activations of the method are stacked up waiting for the third activation of the method to complete. The third reaches the base case, completes, and returns to the second, which can then complete. When the second completes, it returns to the first, which completes and returns to main(). Recursion Diagram Example, cont.
It is true that in a given class there is only one copy of a method’s code which is shared by any calls to it. Objects don’t get their own copies of methods. However, each call to a method is unique and can be identified. Any activation of the method also has its own copies of the values for any variables. Although only the variables are copied, for the purposes of explanation it is useful to illustrate the calling process as if there were multiple copies of the code, one calling the other. Recursion Methods
First Activation of the Recursion Method Such an illustration follows. Here is the call to the method in the main() method with a parameter value of 3: int myResult = PoolClass.poolRack(3); Shown below is the beginning of the first activation of the method. The value of the parameter coming in is 3. The method runs to the line shown in bold face. However, this line does not complete. The call to poolRack() is made, but the addition and the assignment of the result of the arithmetic cannot be done until a return value is received from the call. First Activation of the Recursion Method
First Activation of the Recursion Method, cont The first activation at this point simply waits. public static int poolRack(int numOfRows) { int returnValue; if(numOfRows == 1) returnValue = 1; return returnValue; } else returnValue = numOfRows + poolRack(numOfRows – 1); First Activation of the Recursion Method, cont
Second Activation of the Recursion Method Shown below is the beginning of the second activation of the method. The value of the parameter coming in is 2. The method runs to the line shown in bold face. However, this line does not complete. The call to poolRack() is made, but the addition and the assignment of the result of the arithmetic cannot be done until a return value is received from the call. Second Activation of the Recursion Method
Second Activation of the Recursion Method, cont The second activation at this point simply waits. public static int poolRack(int numOfRows) { int returnValue; if(numOfRows == 1) returnValue = 1; return returnValue; } else returnValue = numOfRows + poolRack(numOfRows – 1); Second Activation of the Recursion Method, cont
Third Activation of the Recursion Method Shown below is the third activation of the method. The value of the parameter coming in is 1. The method runs to the line shown in bold face. This is the base case and at this point the third activation of the method completes. The value 1 is returned to the second activation of the method. public static int poolRack(int numOfRows) { int returnValue; if(numOfRows == 1) returnValue = 1; return returnValue; Third Activation of the Recursion Method
The Previous Activations Resume The second activation of the method now resumes execution. The value 1 is returned to it by the call to poolRack(). This is added to the variable numOfRows, which has the value 2, and assigned to the variable returnValue. This activation of the method runs to completion with the execution of the return statement, shown in bold face, which returns the value 3 to the first activation of the method. returnValue = numOfRows + poolRack(numOfRows – 1); return returnValue; The Previous Activations Resume
The Previous Activations Resume, cont. The first activation of the method now resumes execution. The value 3 is returned to it by the call to poolRack(). This is added to the variable numOfRows, which has the value 3, and assigned to the variable returnValue. This activation of the method runs to completion with the execution of the return statement, shown in bold face, which returns the value 6 to the calling program. returnValue = numOfRows + poolRack(numOfRows – 1); return returnValue; The Previous Activations Resume, cont.
Back to the main() method This return statement returns the value 6 to the main() method. All activations of poolRack() have run to completion and the calling program can finish the execution of the calling statement shown below. The return value is assigned to the variable myResult and the calling program can continue execution. int myResult = PoolClass.poolRack(3); Back to the main() method
The pattern shown above with code fragments can be summarized in the following outline: Call in main program First activation of method, execution till recursive call Second activation of method, execution till recursive call Third activation of method, base case returns a value Second activation resumes, runs to completion returning a value First activation resumes, runs to completion returning a value Calling program resumes execution Summary of Pattern