Programming without loops

 

Towers of Hanoi

In the great temple of Brahma in Benares group of spiritually advanced monks have to move 64 golden disks from one diamond needle to another. And, there is only one other location in the temple (besides the original and destination locations) sacred enough that a pile of disks can be placed there. The 64 disks have different sizes, and the monks must obey two rules:
  1. only one disk can be moved at a time
  2. a bigger disk can never be placed on a top of a smaller disk.
The legend is that, before the monks make the final move to complete the new pile in the new location, the next Maha Pralaya will begin and the temple will turn to dust and the world will end. Is there any truth to this legend?

 

The Tower of Hanoi puzzle was invented by the French mathematician Edouard Lucas in 1883. The puzzle is well known to students of Computer Science since it appears in virtually any introductory text on data structures or algorithms.

 

  applet

 

 

Recursive implementation

public int hanoi(int n)
{
   if (n == 1) return 1;
   else
      return 2*hanoi(n-1) + 1;
}

The idea of calling one function from another immediately suggests the possibility of a function calling itself.

 

 

 

Recurrent equation for the number of moves

T(n) = 2*T(n-1) + 1

 

 

 

Recursive Drawing

 

 

 

For-loops are sooo old fashioned

  Example 1 A sum of natural numbers


             1 + 2 + 3 + ... + n

 

 

             iterative implementation                                           recursive implementation

public int sum(int n)                  public int sumR(int n)
{                                      {
   int res = 0;                          if(n == 1)
   for(int i = 1; i ≤ n; i++)               return 1;
      res = res + i;                     else
                                            return n + sumR(n-1);
   return res;
}                                       }

 

 

Let us trace the sequence of recursive calls of sumR(5)

sumR(5)
   sumR(4)
      sumR(3)
         sumR(2)
            sumR(1)
               return 1
            return 2 + 1
         return 3 + 2 + 1
      return 4 + 3 + 2 + 1
   return 5 + 4 + 3 + 2 + 1

 

 

 

Binary Search

Locate the element x in a sorted array by first comparing x with the middle element and then (if they are not equal) dividing the array into two subarrays and repeat the whole procedure in one of them. If x is less than the middle element you search in the left subarray, otherwise - in the right subarray.

 

Recurrent equation

T(n) = T(n/2) + 1

 

 

public int searchR(int[] a, int key)
{
  return helper(a, key, 0, a.length-1);
}

private int helper(int[] a, int key, int left, int right)
{
   if (left > right) return -1;

   int mid=(left+right)/2;

   if (key == a[mid])  return mid;
   else
   if (key > a[mid])
      return helper(a, key, mid + 1, right);
   else
      return helper(a, key, left, mid - 1);
}

 

 

 

Merge Sort

 

Recurrent equation

T(n) = 2*T(n/2) + n

 

 

public void mergeSort(int [ ] a)
{
   int[] tmp = new int[a.length];
   mergeSort(a, tmp,  0,  a.length - 1);
}


private void mergeSort(int [ ] a, int [ ] tmp, int left, int right)
{
   if( left < right )
   {
      int center = (left + right) / 2;
      mergeSort(a, tmp, left, center);
      mergeSort(a, tmp, center + 1, right);
      merge(a, tmp, left, center + 1, right);
   }
}

 

 

 

Recursive Data Structures

 

Stack - A stack is either empty or consists of a top and the rest which is a stack.

 

Linked List - A linked list is either empty or consists of a node followed by a linked list.

 

Tree - A tree is either empty or consists of one node called root and zero or more subtrees.

 

 

 

Mathematical Induction

 

Recursive programming is directly related to mathematical induction

 

The base case is to prove the statement true for some specific value or values of N.

 

The induction step -- assume that a statement is true for all positive integers less than N,then prove it true for N.

 

 

A few exercises

 

1. Consider the following mystery method:

 

public static void mystery(int level)
{
   if (level == 0)
      System.out.print("*");
   else
   {
      System.out.print("[");
      mystery(level - 1);
      System.out.print(",");
      mystery(level - 1);
      System.out.print("]");
   }

 

Show the output that would be produced by the following calls

 

 

 

2. Examine the following code segment

 

public class Demo
{
   public static void main(String[] ags)
   {
      System.out.println( fun(5) );
   }

   public static int fun(int n)
   {
      if (n == 0)
         return 1;
      else
         return n + fun(n/2);
   }
}

and predict the output

 

 

 

3. Consider the following method. What does it do?

 

public  int foobar(int x, int y)
{
  if (y == 0) return 1;

  if (y%2 == 1)
     return x*foobar(x*x, y/2);
  else
     return foobar(x*x, y/2);
}

 

 

 

Exercise. Write a recursive method that prints the following pattern?

 

#####
####
###
##
#

 

 

#
##
###
####
#####

 

 

 

 

Fibonacci Numbers

 

    0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...

 

Each number is the sum of the two preceding numbers.

 

Fibonacci was born 1170 in Pisa, Italy and died in 1250. His real name is Leonardo Pisano. In 1202 he wrote a book: Liber Abbaci, meaning "Book of Calculating". It helped bring arithmetic in Europe up to Arab standards

 

 

   public int fibonacci(int n)
   {
      if (n ≤ 0)
         return 0;
      else
      if (n == 1)
         return 1
      else
         return fibonacci(n-1) + fibonacci(n-2);
   }

 

 

 

 

 

 

 

 

The Mandelbrot Set

 

The Mandelbrot set is the set of all complex numbers c for which sequence defined by the iteration


f(n+1) = f(n)2  + c, f(0) = c

remains bounded for n = 0, 1, 2, 3, ....

 

 

f(3) = f(2)2  + c =
     = ( f(1)2  + c )2 + c
     = ( ( f(0)2  + c )2  + c )2 + c
     = ( ( c2  + c )2  + c )2 + c

 

 

A few examples.

  • Let c = 1. This sequence is NOT bounded
  • f(0) = 1
               2
    f(1) = f(0)  + 1 = 2
               2
    f(2) = f(1)  + 1 = 5
               2
    f(3) = f(2)  + 1 = 26
    

     

     

  • Let c = 0.1 This sequence has a fixed point
  • f(0) = 0.1
               2
    f(1) = f(0)  + 0.1 = 0.11
               2
    f(2) = f(1)  + 0.1 = 0.1121
               2
    f(3) = f(2)  + 0.1 = 0.112566
    
    ...
    
    f(8) = 0.112702
    

     

     

    Our goal is to draw all complex c = x + I * y for which function f(n ) stays bounded or converges to a fixed point.

     

     

     

     

     

    Linked Lists Recursively

     

    Implement

    public String toString()
    
    public void insertAfter(Object key, Object toInsert)
    
    public void insertBefore(Object key, Object toInsert)
    
    public void delete(Object key)
    
    public LinkedList clone()
    
    public void insertInOrder(Comparable key)
    

     

     

     

     

    Gray Code

    A Gray code is an encoding of numbers so that every transition from one value to the next value involves only one bit change. The following are 2, 3 and 4 bit Gray codes

     
    Decimal Binary Gray
    0 00 00
    1 01 01
    2 10 11
    3 11 10
    Decimal Binary Gray
    0 000 000
    1 001 001
    2 010 011
    3 011 010
    4 100 110
    5 101 111
    6 110 101
    7 111 100
    Decimal Binary Gray
    0 0000 0000
    1 0001 0001
    2 0010 0011
    3 0011 0010
    4 0100 0110
    5 0101 0111
    6 0110 0101
    7 0111 0100
    8 1000 1100

     

     

     

     

     

     

     

     

      The n bit code is generated by

      Write a recursive program that prints out the n-bit binary Gray code.