### Teaching recursion

• What is "recursion"

• Common definition (from Mathematics)

 A recursive definition = a definition that uses the defined term in the definition itself. A recursive function = a function that is expressed (defined) in terms of itself

• What I find as the most helpful clarification of recursion is:

 Recursion is a Divide and Conquer problem solving technique !!!

But:

 Unlike an ordinary divide and conquer strategy, the recusion method poses a major "problem recognization" to the user of recursion

• The general divide an conquer problem solving technique

• Graphically:

Explanation:

 An original problem is "divided" into n sub (smaller/simpler) problems Each sub (smaller/simpler) problems is solved separatedly The solutions of each sub (smaller/simpler) problems are used to solve the original problem

• Important note:

• The divide-and-conquer strategy consist of:

 Solving n + 1 problems !!! (not n problems !!!)

Namely:

• Solve the n sub-problems
• Using the solutions to find the the solution of the original problem

• The common (ordinary) divide-and-conquer problem solving methodology

• The commonly used divide-and-conquer method is as follows:

Characteristics:

• Orignal problem and sub-problems are easily distinguishable

• Sub-problems are often all different

• Sub-problems are often challenging with recognizable effort to solve each one.

• The steps to use the solutions of the sub-problems to solve the original problem is often: trivial

A common way is simply:

 pass the output of solution-i (algorithm) as the input of solution-(i+1) (algorithm)

• The recusion divide-and-conquer problem solving methodology

• The recursion-based divide-and-conquer method is as follows:

Characteristics:

• Orignal problem and sub-problems are identical (i.e., indistinguishable)

• Sub-problems are all the same

• Sub-problems "trivially" solved with unrecognizable effort to solve each one.

• The steps (algorithm) to use the solutions of the sub-problems to solve the original problem is often: challenging

The most uncommon way is:

 pass the output of solution-i (algorithm) as the input of solution-(i+1) (algorithm)

• My take on recursion (through the classic factorial algorithm)

• Divide and conquer:

• I want to solve 10!:

• This is my plan (divide):

• I hire someone to solve 9!:

I do not care how he solves it !!!

All that I care is:

• He can find the correct solution:

• I get the solution back from the hired solver:

• I use the solution to solve my problem:

• How I present the factorial algorithm:

 ``` int fac( int n ) // fac(n) is **me** { int mySol; int Sol1; if ( n == 0 ) { // It's simple enough that I can solve it return 1; } else { Sol1 = some-fac-solver( n - 1 ); // Delegate smaller problem away // and receive his solution mySol = n * Sol1; // Use the helper's solution to // solve my problem return mySol; } } ```

Wait a minite.... I can use fac( ) as some-fac-solver( ) !!!

 ``` int fac( int n ) // fac(n) is **me** { int mySol; int Sol1; if ( n == 0 ) { // It's simple enough that I can solve it return 1; } else { Sol1 = fac( n - 1 ); // Delegate smaller problem away // and receive his solution mySol = n * Sol1; // Use the helper's solution to // solve my problem return mySol; } } ```

Then I execute a small example (e.g., fac(2)) and show student the "recursion"

• Example 2: Tower of Hanoi

• Divide and conquer:

• I want to solve this problem:

• List of useful smaller solutions I can use:

• This is my plan (divide):

• I hire someone to solve this problem:

I do not care how he solves it !!!

All that I care is I get this (correct) solution:

 ``` 1 ---> 3 1 ---> 2 3 ---> 2 ```

• Then, I hire (another) someone to solve this problem:

I do not care how he solves it !!!

All that I care is I get this (correct) solution:

 ``` 2 ---> 1 2 ---> 3 1 ---> 3 ```

• I get the both solutions back from the hired solvers:

Solution 1:

 ``` 1 ---> 3 1 ---> 2 3 ---> 2 ```

Solution 2:

 ``` 2 ---> 1 2 ---> 3 1 ---> 3 ```

• I now use these solutions to find my solution:

My Solution:

 ``` 1 ---> 3 1 ---> 2 3 ---> 2 1 ---> 3 2 ---> 1 2 ---> 3 1 ---> 3 ```

• Again, the first algorithm is not recursive:

 ``` String hanoi( int ndisks, int from, int to, int help ) { String MySol, Sol1, Sol2; if ( ndisks == 1 ) { return from + " ---> " + to + "\n"; // Small enough // Solve it myself } else { Sol1 = some-hanoi-solver( ndisks-1, from, help, to ); // Find sol1 Sol2 = some-hanoi-solver( ndisks-1, help, to, from ); // Find sol2 MySol = Sol1 + (from + " ---> " + to + "\n") + Sol2; return MySol; } } ```

Wait a minite.... I can use hanoi( ) as some-hanoi-solver( ) !!!

 ``` String hanoi( int ndisks, int from, int to, int help ) { String MySol, Sol1, Sol2; if ( ndisks == 1 ) { return from + " ---> " + to + "\n"; // Small enough // Solve it myself } else { Sol1 = hanoi( ndisks-1, from, help, to ); // Find sol1 Sol2 = hanoi( ndisks-1, help, to, from ); // Find sol2 MySol = Sol1 + (from + " ---> " + to + "\n") + Sol2; return MySol; } } ```

Running hanoi( ) is not a good idea.

Rather, to show them the steps of the algorithm, I use an applet: click here

(Make sure to stop half way and show students the smaller solutions)

• How I teach other algorithm that is recursive (= how to make the "problem solving" part non-recursive)

• Merge sort: