1 / 50

Recursion

Recursion. Recursion. Definition: when a function invokes itself A function that invokes itself is said to be Recursive Syntax & Semantics: nothing new. Thinking Non-Recursively. Divide and Conquer: A common problem solving technique:

ailish
Download Presentation

Recursion

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Recursion

  2. Recursion Definition: when a function invokes itself A function that invokes itself is said to be Recursive Syntax & Semantics: nothing new

  3. Thinking Non-Recursively Divide and Conquer: A common problem solving technique: - break problem down into smaller/simpler sub-problems - solve sub-problems - combine sub-solutions into solution

  4. Coding Example Write a function that calculates and returns the Factorial of a given integer. Definition of Factorial: factorial(n), written n! =1 * 2 * 3 *...* n when n = 0 return 1 when n < 0 return 0 (meaning “undefined”)

  5. Coding Example: non-recursive int fact(int n) { // strictly structured, int f; // non-recursive if (n < 0) // sub-solution 1 f = 0; else if (n == 0) // sub-solution 2 f = 1; else { // sub-solution 3 f = 1; for (inti=1; i<=n; i++) f = f * i; } return f; }

  6. Coding Example: non-recursive // simplified non-recursive solution int fact(int n) { int f = 1; if (n < 0) return 0; //undefined for (inti=1; i<=n; i++) f = f * i; return f; }

  7. Thinking Recursively Recursive Divide and Conquer: - Base Case(s): solve the simplest version(s) of the problem, including for “bad input” - Recursive Case(s): - solve a simple piece of the problem - use recursion to solve the rest of the slightly-simplified problem - combine these two sub-solutions into a solution

  8. Coding Example Mathematical Definition of Factorial: n! = • 1 when n = 0 • n * (n-1)! when n > 0 • undefined when n < 0 Note: mathematicians like recursive definitions!!

  9. Coding Example: recursive // strictly structured, recursive solution int fact(int n) { int f; if (n < 0) // base case: bad input f = 0; else if (n == 0) // base case: super easy f = 1; else // recursive case: f = n * fact(n-1); // fairly easy plus return f; // simplified recursive }

  10. Coding Example: recursive // simplified C++ recursive solution int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); }

  11. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  12. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  13. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  14. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  15. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  16. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } fact(2) void main() { cout << fact(3); }

  17. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  18. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  19. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  20. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } fact(1) void main() { cout << fact(3); }

  21. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  22. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  23. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  24. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } fact(0) void main() { cout << fact(3); }

  25. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  26. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  27. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  28. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); }

  29. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } fact(0) = 1 void main() { cout << fact(3); }

  30. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } 1 * 1 = 1 void main() { cout << fact(3); }

  31. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } return 1 void main() { cout << fact(3); }

  32. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } fact(1) = 1 void main() { cout << fact(3); }

  33. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } 2 * 1 = 2 void main() { cout << fact(3); }

  34. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } return 2 void main() { cout << fact(3); }

  35. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } fact(2) = 2 void main() { cout << fact(3); }

  36. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } 3 * 2 = 6 void main() { cout << fact(3); }

  37. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } return 6 void main() { cout << fact(3); }

  38. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); fact(3)=6 }

  39. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); 6 }

  40. Semantic Example: int fact(int n) { if (n < 0) return 0; if (n == 0) return 1; return (n * fact(n-1)); } void main() { cout << fact(3); 6 }

  41. Why Use Recursion? Advantages: - simplified (clearer) coding solutions - some programmers (mathematical thinkers) prefer it. Disadvantages: - very inefficient (memory & invocation overhead) - danger of Stack Overflow(not enough memory)

  42. Practice Example 1: Problem Statement: Write a recursive function that calculates and returns the power of 2 of a given exponent. It should handle negative exponents and an exponent of 0. ex: 23=8 2-2 = 1/22 = ¼ = 0.25 20= 1

  43. Practice Example 1: Design: - name: pow2() - given (argument): integer exponent - returns a float (to handle negative exponents) - D&C: how to handle negative exponents? return 1 / pow2(-exp) - Base Case: pow2(0) = 1 - Recursive Case: pow2(n) = 2 * pow2(n-1)

  44. Practice Example 1: Implementation: strictly structured float pow2(int e) { float p; if (e < 0) p = 1.0 / pow2(-e); else if (e == 0) p = 1.0; else p = 2 * pow2(e-1); return p; }

  45. Practice Example 1: Implementation: C++ simplified float pow2(int e) { if (e < 0) return 1.0/pow2(-e); if (e == 0) return 1.0; return (2 * pow2(e-1)); }

  46. Practice Example 2: Problem Statement: Write a recursive function that counts and returns the number of spaces in a given string. ex: "Go Cats!" 1 "The Univ of Kentucky " 4 "" 0

  47. Practice Example 2: Design: - name: numSpaces() - given (argument): a string - returns an int - Base Case: empty string has 0 spaces - Recursive Case: - count spaces in substring of all but first char - add 1 if first char is space, 0 otherwise

  48. Practice Example 2: Implementation: C++ simplified intnumSpaces(string s) { int ns=0; if (s.empty()) return 0; ns = numSpaces(s.substr(1,-1)); if (s[0] == ' ') ns++; return ns; } // .substr(): the -1 means ”to the end”

  49. Binary Search: intbinSearch(float a[], int f, int e, float s4) { int m = (f + e)/2; // middle index if (f > e) return -1; // not found if (a[m] == s4) return m; if (s4 < a[m]) return binSearch(a[], f, m-1, s4); else return binSearch(a[], m+1, e, s4); }

  50. Vocabulary

More Related