|
|
||
| You are here: | ||
|
Mastery aspect (HL): Recursion, obviously Recursion is a method of implementing program loops that involves a method calling itself. In order to understand this more fully we need to consider a couple of related concepts first.
If the procedure then calls another procedure another return address is placed on the stack. This method calls another - obtainInt. This method, in turn, calls displayMessage
This Applet runs until there is no more stack space available (depends on how much memory your computer has)
Here (count < 25) is the stopping condition. The stack looks something like this at this point:
Most professional programmers would never actually use recursion in real-world programs because of the dangers associated with this technique.
Students should be in the habit of writing comments by now. Let's add pre and post conditions too as these will be required in our dossier .
The first two exercises can typically occur in examination questions.
|
On this page: [ runtime stack | Proper recursion | Worked example | exercises ] Method Calls and the Runtime Stack The values associated with any local identifiers must also be saved. Let's see how information can be stored on a run-time stack for the following sequence of method calls: 1 public void main()
5 y = obtainInt("Please input number 2"); is pushed onto the run-time stack to be executed when the end of procedure obtainInt is encountered.
10 displayMessage( m ); the return address of obtainInt (line 11) and the values of any local variables (the String m) are also pushed onto the runtime stack.
After the displayMessage method is executed the return address (obtainInt - line 11) is popped from the stack together with the values of any local variables. It is perfectly possible for a method to call itself using this technique and for the value of any local variable in any one call to be preserved. Consider the following program: // public class BreakDown extends Applet implements ActionListener public void actionPerformed(ActionEvent thisEvent) breakTheComputer() is a recursive method, one that calls itself; however it lacks an important feature of all (useful) recursive procedures, it never stops executing until there is no more space on the stack causing a run-time error. /** public class PrintUpTo extends Applet implements ActionListener This Applet will print the numbers 24 down to 1 in the TextArea. This is because at the first call with count =1, the if statement causes another call to printUpTo() with count at 2, then another with count at 3 and so on. As these values are pushed on to the stack so is the address of the closing brace } statement, ready to be popped of the stack together with the value of number when the recursion finally "bottoms out" with number at 25. So the 24 stacked up display.append statements are then executed. Had we written the program like this: public void printUpTo(int count) We would have got a different result. Exercise Verify that changing the order of the two statements in printUpTo produces a different result. Explain why. Back to top A Worked Example Recursion can produce elegant solutions to problems in a limited number of cases. First some more examples to help understanding of the concept: Consider the case of calculating the factorial of a given number. A factorial can most easily be defined by a couple of examples: 4 factorial, written 4! is 4 x 3 x 2 x 1 7 factorial written 7! is 7 x 6 x 5 x 4 x 3 x 2 x 1 and so on, in general, n! = n x (n-1) x (n-2) x (n-3) ... x 1 or looked at recursively n! = n x (n-1)! However, this is not the whole story or we could get something like: 3! = 3 x 2! 2! = 2 x 1! 1! = 1 = 0! 0! = 0 * -1! and so on without end. T herefore we need a base case - something to tell us when to stop. For factorials we stop at 0, ie the base case is 0! = 1 (by definition) Thus 1! = 1 x 0!, but 0! = 1 by definition, therefore 1! = 1 x 1 = 1. And so on. So a complete definition (applying factorials only to positive integers) is: 0! = 1 n! = n x (n-1)! for n > 0 This translates fairly easily into a recursive method, as follows: /** A power function can be defined as follows: power(x, n) is equivalent to x^n where x is a real number and n is an integer. The ^ symbol indicates an exponent. Of course, we see that: x^n = x * x^(n-1) and so on. or recursively: x^n = x when n = 1 x^n = x * x^(n-1) when n > 1 1) Write the recursive method power(x, n). 2) Evaluate power (1.2, 3)
The Fibonacci sequence can be defined as follows: FIBO(1) = 1 FIBO(2) = 2 FIBO(n) = FIBO(n-1) + FIBO(n-2) for all n > 2 1) Write the recursive function FIBO 2) Evaluate FIBO(8) The following example, involving two variables, is unlikely to appear in examination questions (although it did occur in the distant past). Ackermann's function A(m,n) is defined as follows: ACKER(m,n) = n + 1 if m = 0 ACKER(m,n) = A(m-1,1) if n = 0 ACKER(m,n) = A(m-1, A(m, n-1)) otherwise 3) Write the recursive function ACKER 4) Evaluate ACKER(3,2) Back to top Special note
|
A lot of dossiers seen by the examiners give very poor/trivial examples of recursion. Many times we see the use of recursion to obtain a value until some validation condition (eg a range check) is passed. It can't be emphasized too strongly that this is a poor, trivial and usually incorrect way of demonstrating mastery of recursion. See the May 2006 Subject Report for further information. Available online at the Online Curriculum Centre. |
|
|
|||
|
Questions or problems related to this web site should be addressed to Richard Jones who asserts his right to be identified as the author and owner of these materials - unless otherwise indicated. Please feel free to use the material presented here and to create links to it for non-commercial purposes; an acknowledgement of the source is required by the Creative Commons licence. Use of materials from this site is conditional upon your having read the additional terms of use on the about page and the Creative Commons Licence. View privacy policy. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. © 2001 - 2009 Richard Jones, PO BOX 246, Cambridge, New Zealand; This page was last modified: May 31, 2009 |