elasticidades Para un análisis más detallado de las consecuencias de este tipo de impuestos, véase
IDEOLOGÍA Silberman y
The recursive function for Fibonacci numbers and the recursive procedure for the Towers of Hanoi have a very similar divide-and-conquer form. Each consists es- sentially of two recursive calls to itself for cases slightly smaller than the original. Why, then, is the Hanoi program as efficient as possible while the Fibonacci pro- gram is very inefficient? The answer comes from considering the size of the output.
InFibonacciwe are calculating only one number, and we wish to complete this cal-
culation in only a few steps, as the iterative function does but the recursive one does not. ForHanoi, on the other hand, the size of the output is the number of instructions to be printed, which increases exponentially with the number of disks. Hence any procedure for the Towers of Hanoi will necessarily require time that increases exponentially in the number of disks.
5.2.5 Guidelines and Conclusions
In making a decision, then, about whether to write a particular algorithm in recur- sive or nonrecursive form, a good starting point is to consider the recursion tree.
Section 5.2 • Principles of Recursion
181
If it has a simple form, the iterative version may be better. If it involves dupli- cate tasks, then data structures other than stacks will be appropriate, and the need for recursion may disappear. If the recursion tree appears quite bushy, with little duplication of tasks, then recursion is likely the natural method.
The stack used to resolve recursion can be regarded as a list of postponed obligations for the program. If this list can be easily constructed in advance, then iteration is probably better; if not, recursion may be. Recursion is something of a top-down approach to problem solving; it divides the problem into pieces or top-down design
selects out one key step, postponing the rest. Iteration is more of a bottom-up approach; it begins with what is known and from this constructs the solution step by step.
It is always true that recursion can be replaced by iteration and stacks. It is also true, conversely (see the references for the proof), that any (iterative) program that stacks or recursion
manipulates a stack can be replaced by a recursive program with no stack. Thus the careful programmer should not only ask whether recursion should be removed, but should also ask, when a program involves stacks, whether the introduction of recursion might produce a more natural and understandable program that could lead to improvements in the approach and in the results.
Exercises 5.2
E1. In the recursive calculation of Fn, determine exactly how many times each smaller Fibonacci number will be calculated. From this, determine the order- of-magnitude time and space requirements of the recursive function. [You may find out either by setting up and solving a recurrence relation (top-down ap- proach), or by finding the answer in simple cases and proving it more generally by mathematical induction (bottom-up approach).]E2. Thegreatest common divisor(gcd) of two positive integers is the largest integer that divides both of them. Thus, for example, the gcd of 8 and 12 is 4, the gcd of 9 and 18 is 9, and the gcd of 16 and 25 is 1.
(a) Write a nonrecursive functionintgcd(intx, inty), wherexandyare required to be positive integers, that searches through the positive integers until it finds the largest integer dividing bothxandy.
(b) Write a recursive function int gcd(int x, int y)that implements Euclid’s algorithm: Ify= 0, then the gcd ofxandyisx; otherwise the gcd ofxand
yis the same as the gcd ofyandx % y.2
(c) Rewrite the function of part (b) into iterative form.
(d) Discuss the advantages and disadvantages of each of these methods.
2 Recall that % is the modulus operator: The result ofx % yis the remainder after the integer
E3. The binomial coefficients may be defined by the following recurrence relation, which is the idea ofPascal’s triangle. The top of Pascal’s triangle is shown in Figure 5.11. C(n,0)=1 and C(n, n)=1 forn≥0. C(n, k)=C(n−1, k)+C(n−1, k−1) forn > k >0. 134 1 1 6 5 15 10 20 10 15 5 6 1 1 1 1 4 3 6 3 4 1 1 1 1 2 1 1 1 1 6 15 20 15 6 1 1 5 10 10 5 1 1 4 6 4 1 1 3 3 1 1 2 1 1 1 1 6 5 4 3 2 1 0 2 0 1 3 4 5 6
(a) Symmetric form (b) In square array
Figure 5.11. The top of Pascal’s triangle of binomial coefficients
(a) Write a recursive function to generateC(n, k)by the foregoing formula. (b) Draw the recursion tree for calculatingC(6,4).
(c) Use a square array withnindicating the row andkthe column, and write a nonrecursive program to generate Pascal’s triangle in the lower left half of the array, that is, in the entries for whichk≤n.
(d) Write a nonrecursive program that uses neither an array nor a stack to calculateC(n, k)for arbitraryn≥k≥0.
(e) Determine the approximate space and time requirements for each of the algorithms devised in parts (a), (c), and (d).
E4. Ackermann’s function, defined as follows, is a standard device to determine how well recursion is implemented on a computer.
A(0, n)=n+1 forn≥0.
A(m,0)=A(m−1,1) form >0.
A(m, n)=A(m−1, A(m, n−1)) form >0 andn >0. (a) Write a recursive function to calculate Ackermann’s function.
(b) Calculate the following values. If it is impossible to obtain any of these values, explain why.
A(0,0) A(0,9) A(1,8) A(2,2) A(2,0) A(2,3) A(3,2) A(4,2) A(4,3) A(4,0) (c) Write a nonrecursive function to calculate Ackermann’s function.