1 / 46

Round and round recursion: the good, the bad, the ugly, the hidden

Round and round recursion: the good, the bad, the ugly, the hidden. ACSE 2006 Talk Troy Vasiga Lecturer, University of Waterloo Director, CCC. Outline. Recursion defined Real-world examples ("The hidden") Benefits ("The good") Examples How it works Pitfalls ("The bad")

jadon
Download Presentation

Round and round recursion: the good, the bad, the ugly, the hidden

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. Round and round recursion: the good, the bad, the ugly, the hidden ACSE 2006 Talk Troy Vasiga Lecturer, University of Waterloo Director, CCC

  2. Outline • Recursion defined • Real-world examples ("The hidden") • Benefits ("The good") • Examples • How it works • Pitfalls ("The bad") • Larger pitfalls ("The ugly") ACSE 2006

  3. Recursion Defined • See "Recursion" ACSE 2006

  4. Real Definition • Recursion is defining a function/procedure/structure using the function/procedure/structure itself in the definition ACSE 2006

  5. A better definition of Recursion • If you still don't understand recursion, see "Recursion" ACSE 2006

  6. A more formal definition • A recursive definition will rely on a recursive definition and some base case(s) • Example: define object X of size n using objects of type X of size k (1 <= k < n) ACSE 2006

  7. Example • Babuska (Russian) dolls ACSE 2006

  8. Real-World Example • Shells ACSE 2006

  9. Real-World Example • Flowers ACSE 2006

  10. Real-World Example • Definition of a human • I was created by my parents • ... who were created by their parents • … (religious/biological discussion follows) ACSE 2006

  11. Using Recursion in CS • Less code implies less errors • Natural way of thinking • mathematical • inductive reasoning • allows both top-down and bottom-up approaches ACSE 2006

  12. (Linked) Lists • C version of linked lists typedef struct list_elem { int val; struct list_elem * next; } node; ACSE 2006

  13. Recursive Ordered Insert void insert(node** head, int newValue) { node* newNode = malloc(sizeof(node)); newNode->val = newValue; newNode->next = NULL; if (*head == NULL) { *head = newNode; } else if ((*head)->next == NULL) { (*head)->next = newNode; } else if ((*head)->next->val > newNode->val) { newNode->next = (*head)->next; (*head)->next = newNode; } else { insert(&(*head)->next, newValue); } } ACSE 2006

  14. Recursive Length int length(node* head) { if (head == NULL) { return 0; } else { return 1+length(head->next); } } ACSE 2006

  15. Scheme lists • In Scheme a list is • the empty list () or • a head element, followed by a list containing the rest of the elements • Examples: • () • (1 2 3 4) • ((a b) (c d) (e f)) ACSE 2006

  16. Scheme lists • How to access elements from a list? • car = head • cdr = tail (rest of the list) • Examples: • (car '(a b c)) => a • (cdr '(a b c)) => (b c) • (car (cdr '(a b c))) => b • (caddr '(a b c)) => c ACSE 2006

  17. Length in Scheme (define reclength (lambda (L) (if (eq? L '()) 0 (+ 1 (reclength (cdr L))) ) ) ) ACSE 2006

  18. Am I right? • Prove it! • Base case: (length '()) => 0 • Assume true for list of length k >= 0 • If length is k+1, our algorithm computes • 1+length(list of size k), which it can do correctly. • Our algorithm is correct. Q.E.D. ACSE 2006

  19. Trees • Extend linked lists in two dimensions • not just "next" but "left" or "right" • Definition • A tree is: • empty, or • is a node which contains • a value • a left tree • a right tree ACSE 2006

  20. Binary Search Trees • In fact, we will insist the following property is also true: • all nodes in the left subtree of a node are less than or equal to the value in the node • all nodes in the right subtree of a node are greater than the value in the node ACSE 2006

  21. 9 6 8 4 Picture 10 15 12 23 19 ACSE 2006

  22. Java code public class Node { private int value; private Node left; private Node right; // other methods are straightforward } ACSE 2006

  23. Using trees recursively public void insert(Node root, int newValue) { if (newValue <= root.getValue()) { if (root.getLeft() == null) { root.setLeft(new Node(newValue)); } else { insert(root.getLeft(), newValue); } } else { if (root.getRight() == null) { root.setRight(new Node(newValue)); } else { insert(root.getRight(), newValue); } } } ACSE 2006

  24. Inorder traversal public static void inOrder(Node n) { if (n != null) { inOrder(n.getLeft()); System.out.print(n.getValue()+" "); inOrder(n.getRight()); } } ACSE 2006

  25. Inorder observations • Output on original tree 4 6 8 9 10 12 15 19 23 • Print out "in" the middle • What if we change the printing part? • Exercise: Try to do this without recursion • (Answer: It is really nasty.) ACSE 2006

  26. Preorder traversal public void preOrder(Node n) { if (n != null) { System.out.print(n.getValue()+" "); preOrder(n.getLeft()); preOrder(n.getRight()); } } ACSE 2006

  27. + / - 4 * 10 5 2 7 Using traversals • Arithmetic expression trees • internal nodes are operators • leave nodes are operands ACSE 2006

  28. Using traversals • Notice the inorder traversal gives: 2 * 7 - 4 + 10 / 5 • Notice the preorder traversal gives: + - * 2 7 4 / 10 5 • TI, anyone? ACSE 2006

  29. Recursion always works • Theorem: Every iterative loop can be rewritten as a recursive call ACSE 2006

  30. How recursion "works" • Implicit call stack • Every call to a function places an "activation" record on top of the stack in RAM • Activation record remember the current state • Stack is built up, and is empty when we return to the main caller ACSE 2006

  31. Avoiding Recursion is Ugly • Consider quicksort • Sorts an array into increasing order ACSE 2006

  32. Recursive Quicksort • Recursive void quicksort (int[] a, int lo, int hi) { int i=lo, j=hi, h; int x=a[(lo+hi)/2]; do { while (a[i]<x) i++; while (a[j]>x) j--; if (i<=j) { h=a[i]; a[i]=a[j]; a[j]=h; i++; j--; } } while (i<=j); if (lo<j) quicksort(a, lo, j); if (i<hi) quicksort(a, i, hi); } ACSE 2006

  33. Iterative Quicksort QuickSort(A,First,Last) { var v,sp,L,L2,p,r,r2; sp=0; Push(First,Last); while( sp > 0 ) { Pop(L, r)/2; while( L < r) { p = (L+r)/2; v = A[p].key; L2 = L; r2 = r; while( L2 < r2 ) { while( A[L2].key < v ) { L2 = L2+L; } // ... ACSE 2006

  34. More iterative Quicksort while( A[r2].key > v ) { r2 = r2-L; } if(L2 <= r2 ) { if(L2 equals r2) { Swap(A[L2],A[r2]); } L2 = L2 + L; r2 = r2 - L; } } // ... ACSE 2006

  35. Yet more iterative Quicksort if(r2-L > r-L2) { if(L<r2) { Push(L,r2); } L = L2; } else { if(L2 < r) { Push(L2,r); r = r2; } } } // end while( L < r ) } // end while( sp>0 ) } // end QuickSort ACSE 2006

  36. Bad Fibonacci, Bad • f(0) = 0 • f(1) = 1 • f(n) = f(n-1) + f(n-2) ACSE 2006

  37. Dynamic Programming • Recursion leads to a very powerful problem solving technique called Dynamic Programming • Essentially, don't use the recursive call, but write a recurrence relation and solve it from the bottom-up ACSE 2006

  38. Shortest Paths using DP • A shortest path is a path between two vertices that has minimum weight • Number the vertices of the graph from 1..n • Let D(k, i, j) mean the shortest path between vertices i and j that uses only vertices 1, …, k ACSE 2006

  39. Base case • D(0, i, j) = • 0 if i=j • w(i,j) if there is an edge (i,j) •  otherwise ACSE 2006

  40. Recursive case • D(k+1, i, j) uses either vertex k+1 or it doesn't • If it doesn't, • D(k+1, i, j) = D(k,i,j) • If it does, • D(k+1, i, j) = D(k, i, k+1) + D(k, k+1, j) • So, D(k+1,i,j) is the minimum of these two ACSE 2006

  41. Filling in the table • In fact, filling in the table is done without using recursion • As we did in the Fibonacci case, except now, we are in more than one dimension ACSE 2006

  42. Ugly: Recursive Main • Don't do this in Java public class RecUgly { public static int factorial(int n) { if (n <= 0) { return 1; } else { return n*factorial(n-1); } } public static void main(String[] args) { System.out.println(factorial(11)); } } ACSE 2006

  43. Context-Free Grammars • Describe very complex things using recursion S -> (S) S -> SS S ->  ACSE 2006

  44. Mathematical beauty • Koch curves using Lindenmayer systems • Let F mean "forward", + mean "right" and - mean "left" • Koch curve • Rule: F -> F-F++F-F (starting with F) • Koch snowflake • Start with F++F++F instead! ACSE 2006

  45. Dragon curve • X -> X+YF+, Y->-FX-Y (start with FX) ACSE 2006

  46. Conclusion • Recursion is • Beautiful • Natural (in many senses) • Mathematically precise • Simple • Powerful • Recursive ACSE 2006

More Related