Download section 2.3 handout

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Vincent's theorem wikipedia , lookup

Strähle construction wikipedia , lookup

Arithmetic wikipedia , lookup

Horner's method wikipedia , lookup

Transcript
Decision-Making and Repetition
2.2 Recursion
Introduction
A recursive method is a method that call itself. You may already be familiar with the
factorial function (N!) in mathematics.
For any positive integer N, N! is defined to be the product of all integers between 1 and N
inclusive.
N! = 1 * 2 * 3 * 4 * 5 * … N-1 * N
Another way of expressing N! is by using recursion. i.e. by having the function call itself.
N! = N * (N – 1)!
where N > 1,
and 1! = 1
Note that the recursion terminates when N = 1. This is known as the base case.
This can be visualised as follows:
5! = 5 * 4!
= 5 * 4 * 3!
= 5 * 4 * 3 * 2!
= 5 * 4 * 3 * 2 * 1!
= 5 * 4 * 3 * 2 * 1
From this example we can see that without a base case, the recursions could go on
indefinitely.
The code in a recursive method must be have both the recursive part and the base case.
Although recursion can sometimes provide elegant solutions based on recursive thinking as
shown above, this does not mean that recursive solutions are the best. Recursion makes huge
demands on memory, and should only be used when it significantly simplifies the code.
1
Decision-Making and Repetition
Recursive Method Example
A recursive method is a method that calls itself.
For example,
below is a recursive method which prints out asterisks on line or the word “Done!”
public static void drawStars(int rows)
{
if(rows == 0)
System.out.println("There are no stars in this row!");
else
{
for(int i = 1; i <= rows; i++)
System.out.print("*");
System.out.println();
drawStars(rows - 1); //drawStars calls itself
}
}
Note that this method takes in an integer parameter. So instead of using String [] args
inside the parenthesis following the method name, we have int rows – highlighted above.
The base case is rows == 0, and the method calls itself using the parameter rows – 1.
As we will see in the demos, when the drawStars method is run we will need to enter the
specific value we want it to use during the execution. For example, when the integer 5 is
entered, we get the following result:
*****
****
***
**
*
There are no stars in this row!
Most of the time, return methods require a return statement as part of their definition. So it is
worth spending some time discussing these.
2
Decision-Making and Repetition
Return Statements
Until now, our programs have included a main method of the form:
public static void main (String[] args)
Control is automatically passed on to a main method within a program when a Java program
is executed. For this reason, a Java application (or program) can only have one main
method.
A main method is void, which means that does not return any value. This is why so far we
have had to use the System.out.println to output values computed within a main
method.
A non-void method must return a specific data type. For example, the template class provided
when a new class is created in BlueJ includes the non-void method shown below.
public int sampleMethod(int y)
{
// put your code here
return x + y;
}
sampleMethod returns a value of type int, and therefore must contain a return statement
as part of its definition.
Methods with a non-void return type are usually written inside a class representing an object,
and later called by the main method or in another class—sometimes referred to as the driver
class.
Here is an example:
3
Decision-Making and Repetition
Assume the following method deposit is part of a class which represents the bank
accounts of customers at a certain bank.
public double deposit (double amount)
{
if (amount < 0) // deposit value is negative
{
System.out.println ();
System.out.println ("Error: Deposit amount is invalid.");
}
else
balance += amount;
return balance;
}
This method could be called within another class – call it CustomerAccounts – using the
following statement, which is used to deposit £500 into a Mr Smith’s account
double smithBalance = smithAcc.deposit (800.00);
//note call to deposit method
Following which the new balance could be printed out with the following statement written
inside CustomerAccounts.
System.out.println ("Smith balance after deposit: " + smithBalance);
Writing Recursive Methods
The drawStars method above is an example of tail recursion, since the recursive call is
the last statement in the method. When drawStars is called within the method, the value of
the parameter must be smaller than that used in the original call. In other words, the value
most continue to progress towards the base case. Without this type of set up, the method will
continue to execute infinitely; this is known as infinite recursion.
Two well-known examples of recursion are the Fibonacci sequence and the Tower of Hanoi;
both of these are covered in the Mathematics sections this week. This section concludes with
an analysis of a method to find the nth Fibonacci number.
4
Decision-Making and Repetition
Given the Fibonacci sequence 1, 1, 2, 3, 5, 8, 13, … let us calculate the nth Fibonacci
number.
Recall that except for the first two numbers in the sequence, every Fibonacci number is the
sum of the preceding two numbers. This is written mathematically as,
𝐹𝑖𝑏(𝑛) = {
1
𝑖𝑓 𝑛 = 1 𝑜𝑟 2
𝐹𝑖𝑏(𝑛 − 1) + 𝐹𝑖𝑏(𝑛 − 2) 𝑖𝑓 𝑛 ≥ 3
Once it has been written in this recursive format, it becomes straightforward to write Java
code to calculate the nth Fibonacci number. This is shown below.
public static int fibo(int n)
{
if (n == 1 || n == 2)
return 1;
else
return fibo(n - 1) + fibo (n - 2);
}
fibo also has tail recursion since the recursive call is the last statement in the method. But
notice that there are actually two recursive calls—fibo(n - 1) and fibo (n - 2).
Actually,
calling fibo(n) for n = 3, calls fibo(2) and fibo(1); that’s two recursive calls.
Now fibo(4) = fibo(3) + fibo(2). From above, fibo(3)makes two further
recursive calls, plus one more. So there are four recursive calls.
5
Decision-Making and Repetition
We can see how complex this computation gets very quickly from the tree structure for
fibo(5)shown below.
fibo(5)
fibo(4)
fibo(3)
fibo(2)
fibo(3)
fibo(2)
fibo(2)
fibo(1)
This shows that executing fibo(5) requires a further 8 calls to fibo!
6
fibo(1)