1 / 16

Class 6 - Recursion on Lists

Class 6 - Recursion on Lists. More recursive methods on lists. Recursion on lists (review). Writing recursive methods on lists follows same principle as for integers: To compute f(L) , assume f(L’) can be calculated for lists L’ smaller than L , and use f(L’) to calculate f(L) .

cachet
Download Presentation

Class 6 - Recursion on Lists

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. Class 6 - Recursion on Lists • More recursive methods on lists

  2. Recursion on lists (review) Writing recursive methods on lists follows same principle as for integers: • To compute f(L), assume f(L’) can be calculated for lists L’ smaller than L, and use f(L’) to calculate f(L). • Some lists are small enough for f to be calculated directly

  3. Example: joining lists Given lists L and M, create a list consisting of the elements of Lfollowed by the elements of M. • Assume you can append the tail of L and M (i.e. append(L.tl(), M)); how can you append L and M?

  4. Example: joining lists (cont.) static IntList append (IntList L, IntList M) { if (L.empty()) return M; else return IL.cons(L.hd(), append(L.tl(), M)); }

  5. Example: addtoend Given list L and integeri, construct a list that contains the elements of L with iat the end. static IntList addtoend (IntList L, int i) { return append(L, IL.cons(i, IL.nil)); }

  6. Example: finding maximum element Find the maximum integer in a non-empty list. • Assume you can find the maximum element of the tail (if the tail is non-empty)

  7. Example: finding maximum element (cont.) static int max (IntList L) { if ((L.tl().empty())) return L.hd(); else { int m = max(L.tl()); return (L.hd() > m) ? L.hd(): m; } }

  8. Example: list reversal Given list L, construct the reversal of L. • Assume you can reverse the tail of L. How can you place the head of L in the reversal of the tail of L so as to get the reversal of L itself?

  9. Example: list reversal (cont.) static IntList reverse (IntList L) { if (L.empty()) return L; else return addtoend(reverse(L.tl()), L.hd()); }

  10. Analysis of list reversal reverse is rather slow. Consider how many method calls it makes in relation to the size of its argument. Note that addtoend(L) calls itself recursively n times, where n is the length of L. How many method calls does reverse(L) make?

  11. Analysis of list reversal (cont.) • After recursive call to itself, it calls addtoend, on a list of length n-1. So this makes n-1 calls to addtoend. • Now consider the first recursive call. It in turn has a recursive call; after that inner recursive call, there is a call to addtoend, which entails n-2 calls to addtoend. • Continuing in this way, there is a call to addtoend that involves n-3 calls, one involving n-4 calls, etc.

  12. Analysis of list reversal (cont.) Thus, the total number of calls to addtoend is (n-1) + (n-2) + … + 1, which equals n(n-1)/2  n2. This is a much larger number than n itself.

  13. Faster list reversal To avoid the quadratic cost of reversal, we can define another version, which we will call rev (just to distinguish it). The important trick is that rev uses an auxiliary (helper) method rev1 with type IntList rev1 (Intlist L, IntList M) rev1(L,M) is defined to return the reversal of Lappended toM.

  14. Faster list reversal (cont.) rev1 can be defined recursively. The key observation is this one: Placing the reversal of L onto the front of M is the same thing as placing the reversal of the tail of L onto cons(hd(L), M). For example, if we want to place the reversal of 1,2,3 onto the front of list 4,5 - obtaining 3,2,1,4,5 - we can just as well place the reversal of 2,3 onto the front of 1,4,5.

  15. Faster list reversal (cont.) This observation leads to: static IntList rev1 (IntList L, IntList M) { if (L.empty()) return M; else return rev1(L.tl(), IL.cons(L.hd(), M)); } Note that this requires only n method calls, where n is the length of L.

  16. Faster list reversal (cont.) We can easily program rev once we’ve got rev1. static IntList rev (IntList L) { return rev1(L, IL.nil); }

More Related