Universidad Carlos III de Madrid

Ingeniería de Telecomunicación

Enero-Mayo 2010 / January-May 2010

Recursion

Objectives Section Learning Objectives

Learning Objectives for Recursion

  • Define the concept of recursion (Bloom 1*)

  • Describe the successive computations carried out when evaluating a recursive method (Bloom 2*)

  • Convert a tail-recursive method into iterative form (Bloom 3*)

  • Classify a recursive method into one of the types of recursion studied (Bloom 3*)

  • Given a recursive method, find the domain of convergence for some simple cases (Bloom 4)

  • Write down a recursive method for a given problem (Bloom 5)

  • Compare different recursive methods that solve the same problem (Bloom 6)

Lecture Section Session 1 (lecture): Recursion

Material

Lab Section Session 2 (lab): Recursion

Material

Material (with solutions)

Learning Pills Section Learning Pills

¿DID YOU KNOW THAT...?

The following code that calculates the harmonic series is wrong, and it will eventually launch a StackOverflowError exception:

public double h(int n) {
  return h(n-1) + 1.0/n;
} 					

¿DID YOU KNOW THAT...?

The recursive harmonic function, even though with its base case defined, will still launching an StackOverflowError exception:

public double h(int n) {
 if (n==1) return 1.0;
 return h(n-1) + 1.0/n;
}					

¿DID YOU KNOW THAT...?

A tail-recursion function can be converted into an iteration-based one. In a function, when there is a recursive call and this call is the last statement in the function, then this function can be converted into an iterative function. The next code has its iterative version immediately.

public void hanoi(int n,char from,char to,char ch) {
 if (n==1)
  System.out.println("Move 1 from"+from+"to"+to);
 else
  if (n>1) {
   hanoi(n-1, from, ch, to);
   System.out.println("Move "+n+"from"+from+"to"+ to);
   hanoi(n-1, ch,to, from);
  }
}

¿DID YOU KNOW THAT...?

Sometimes recursion is not efficient. For example, the Fibonacci series can be calculated by the following recursive method.However, the time it takes grows exponentially with n, making this method useless, except for n with small values.

		
public static long fib(int n) {
  if (n <= 1) 
   return n;
  else 
   return fib(n-1) + fib(n-2);
  }
}
with fib(0) = 0 and fib(1) = 1

¿DID YOU KNOW THAT...?

The previous non-linear recursive method can be optimized for the Fibonacci series, transforming it into a linear recursive method more efficient.

¿DID YOU KNOW THAT...?

In general, if there is a recursive method and an iterative method to solve the the same problem, it is preferred to use the iterative version due to efficiency.

¿DID YOU KNOW THAT...?

A sorting algorithm, such as QuickSort, of logarithmic order, is always faster than one of quadratic order O(n^2), such as the BubbleSort, when n grows bigger.

¿DID YOU KNOW THAT...?

If we are going to work with small values of n, the complexity order of the recursive algorithm is not significant and can be a problem instead.

¿DID YOU KNOW THAT...?

Depending on the data size of an algorithm, the evolution of its temporal cost gets bigger, taking into account its complexity orders and its multiplying constants.

¿DID YOU KNOW THAT...?

Backtracking algorithms are generally solved recursively.

¿DID YOU KNOW THAT...?

You can verify if you have correctly implemented a recursive method by answering 3 questions about the base case and the non-base cases.

¿DID YOU KNOW THAT...?

The "divide-and-conquer" technique using recursion, and applying it to the sorting algorithm "QuickSort", allows to diminish the average execution time to a logarithmic order O(log n).

¿DID YOU KNOW THAT...?

Dynamic programming allows to solve sub-problems generated by a recursive design in a non-recursive version, storing the values of the solutions in a table.

¿DID YOU KNOW THAT...?

The complexity of this piece of code is O(n^2)

for (int i = 0; i < n; i++) {
 for (int k = 0; k < i; i++) {
  m[i][k] = a[i] * a[k]
 }
}