The printInt method does obey recursion rule 1; it does have a base case,
namely:
The call printTwoInts(3) causes the following to be printed:
Question 1:
The call factorial(3) leads to three recursive calls; when all calls
are still active, the runtime stack would be as shown below (showing just
the values of parameter N).
The values returnedby each call are also shown.
Question 2:
The iterative version of factorial will return -1 as the result of the call
factorial(-1).
The recursive version will go into an infinite recursion (because the base
case, N==0, will never be reached).
Since, mathematically, factorial is undefined for negative numbers,
a call to factorial with a negative number should cause an exception.
This is easily done for the iterative version:
For the recursive version, we could change the method to:
Test Yourself #1
if (k == 0) return;
It obeys recursion rule 2 in a sense; the code:
printInt( k - 1 );
makes progress toward the base case as long as k is greater than zero.
However, all calls with actual parameters less than zero will cause
an infinite recursion.
Assuming that the intention is to print only positive values,
this could be fixed by changing the base case to:
if (k <= 0) return;
Test Yourself #2
From before recursion: 3
From before recursion: 2
From before recursion: 1
From after recursion: 1
From after recursion: 2
From after recursion: 3
Test Yourself #3
Returned value
+------+ --------------
| N: 0 | <--- top of stack 1
+------+
+------+
| N: 1 | 1
+------+
+------+
| N: 2 | 2
+------+
+------+
| N: 3 | 6
+------+
int factorial (int N) {
if (N < 0)throw new NegativeValueException();
if (N == 0) return 1;
int tmp = 1;
for (int k=N; k>1; k--) tmp = tmp*k;
return (tmp);
}
(where NegativeValueException would have to be defined as a public exception).
int factorial (int N) {
if (N < 0)throw new NegativeValueException();
if (N == 0) return 1;
else return (N*factorial(N-1));
}
However, the problem with this is that the check for N < 0 will be made
on every call, including the recursive calls where it cannot be true.
This makes the method slightly less efficient.
A better solution would be to make the check once, the first time
factorial is called, and then use an auxiliary, recusive method with no
check:
int factorial (int N) {
if (N < 0)throw new NegativeValueException();
else return factAux(N);
}
int factAux(int N) {
if (N == 0) return 1;
else return (N*factAux(N-1));
}