CSCI 162 - Lecture 11 - Chapter 8: Recursive Thinking

Instructor's Class Notes

     

  1. Recursive Thinking - The expectation that one can find a subtask that is a simpler version of a larger problem one is already trying to solve.
  2.  

  3. Recursive Methods - A method that calls itself is a recursive method. Let's start by looking at a very simple example:

    a. Countdown:
    
    	public static void countdown(int n) {
    		System.out.println(n);
    		if (n>1) {
    			countdown(n-1);
    		}
    	}
    Output (n = 10):
    
    	10
    	9
    	8
    	7
    	6
    	5
    	4
    	3
    	2
    	1
    Thoughts: - Seems simple enough. The method prints the number passed in, calls itself passing to itself that same number reduced by one and stops calling itself when n is equal to 1.

    b. Countup:
    
    	public static void countup(int n) {
    		if (n>1) {
    			countup(n-1);
    		}
    		System.out.println(n);
    	}
    Output (n = 10):
    
    	1
    	2
    	3
    	4
    	5
    	6
    	7
    	8
    	9
    	10
    Thoughts: - Wait a minute! Why do the numbers count down? The answer is found in tracing a recursive method which we will discuss below.
  4.  

  5. writeVertical - Consider a more complex recursive method that prints a large integer vertically, with each digit printed on its own line. For example, the number 4627 would be printed as:
    
    	4
    	6
    	2
    	7
    Psuedocode for the recursive method is as follow:
    
    	// Printing the digits of a non-negative number, stacked vertically
    	if (the number has only one digit)
    		Write that digit.
    	else {
    		Write the digits of number/10 stacked vertically.
    		Write the single digit of number % 10.
    	}		
    			
    Actual Code:
    
    	public static void writeVertical(int number) {
    	   if (number < 10)
    		   System.out.println(number);      // Write the one digit.
    	   else
    	   {
    		   writeVertical(number/10);        // Write all but the last digit.
    		   System.out.println(number % 10); // Write the last digit.
    	   } 
    	}			
    			
    Terminology:
  6.  

  7. Tracing Recursive Methods - Let's consider the writeVertical method when coming up with a technique for tracing a recursive method. It is important to understand how to use the execution stack of activation records as aids in tracing the method calls.

    The book shows a "bubble" approach to describing the activation records and the execution stack. For our lecture, we will essentially trace in a similar manner but use a table instead. The rows of the table below corresponds the call states, in order, when executing:
       writeVertical(375);
  8. Callnumberwhich case
    (recursive, stopping, or return)?
    output this callnext recursive callon the stack
    writeVerical(375)375recursivenothingwriteVertical(37);375
    writeVerical(37)37recursivenothingwriteVertical(3);37,
    375
    writeVerical(3)3stopping337,
    375
    return from recursionreturn7
    375
    return from recursionreturn5

     

  9. Recursive Examples - What will each of the following recursive methods output?
    
    	public static void f1(int n) {
    		System.out.println(n); 
    		if (n > 1)
    			f1(n-1);
    	}
    	
    	public static void f2(int n) {
    		if (n > 1)
    		    f2(n-1);
    		System.out.println(n);
    	}
    	
    	public static void f3(int n) {
    		System.out.println(n);
    		if (n > 1)
    			f3(n-1); 
    		System.out.println(n);
    	}
    	
    	public static void cheers(int n) {
    		if (n <= 1) 
    			System.out.println("Hurrah");
    		else {
    			System.out.println("Hip");
    			cheers(n-1);
    		}
    	}
    	
    	public static void cheers2(int n) {
    		if (n > 1)  {
    			cheers2(n-1);
    			System.out.println("Hip");
    		} else {
    			System.out.println("Hurrah");
    		}
    	}
    
    	public static void cheers3(int n) {
    		if (n > 1)  {
    			System.out.println("Hip");
    			cheers3(n-1);
    			System.out.println("Hip");
    		} else {
    			System.out.println("Hurrah");
    		}
    	}
    	
    	public static void cheers4(int n, int max) {
    		if (n > max/2)  {
    			System.out.println("Hip");
    			cheers4(n-1, max);
    			System.out.println("Hip");
    		} else {
    			System.out.println("Hurrah");
    		}
    	}
    
    	public static void recurse1(int n) {
    		System.out.println(n);
    		if (n>1)
    			recurse1(n-1);
    		System.out.println(n);
    	}
    	
    	public static void starclamation(int n) {
    		System.out.println("*");
    		if (n>1)
    			starclamation(n-1);
    		System.out.println("!");
    		
    	}