160 likes | 302 Views
Class 5 - Lists. The list data type Recursive methods on lists. Data structures. Contain large amounts of data Allow for access to that data Many different data structures, allowing efficiency for various operations. Lists.
E N D
Class 5 - Lists • The list data type • Recursive methods on lists
Data structures • Contain large amounts of data • Allow for access to that data • Many different data structures, allowing efficiency for various operations.
Lists Lists are a simple data structure in which data are stored in a row. We will talk first about lists of integers: x0, x1, ..., xn-1 (n >= 0) Elements can be added and removed only at the beginning (x0) --- We don’t consider mutable lists.
Lists (cont.) Terminology: • First element (x0) is head of the list • List of remaining elements (x1, ..., xn-1) is tail of the list • Adding a new element to the front is called consing (for “constructing”) • The nil list is the list with no elements (n=0)
List operations • We assume a type IntList, for variables that contain such lists • We assume a class IL that defines the following class method: • IntList cons (int i, IntList L) - construct list containing i at front • And a class variable: • IntList nil - the empty (zero-element) list
List operations (cont.) • IntList objects have the following instance methods: • int hd () - return head of the list • IntList tl () - return tail of the list • boolean empty ()-is the list empty?
Examples of list operations Suppose L is the list 2, 3, 5, 7 IL.cons(2,IL.cons(3,IL.cons(5,IL.cons(7,IL.nil)))) • L.hd() returns 2 • L.tl() returns the list 3, 5, 7 • L.empty() returns false • IL.cons(13, L) returns the list 13, 2, 3, 5, 7 • IL.cons(13, L.tl()) returns the list13, 3, 5, 7 • L.tl().tl() returns the list 5, 7
Example We assume we have defined the classes IntList and IL as described above. public static void main (String[] args) { IntList L = IL.nil; L = IL.cons(5, L); L = IL.cons(10, L); System.out.println(L.hd()); System.out.println(L.tl().hd()); }
Recursion on lists Writing recursive methods on lists follows the 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
Example: printing lists Print all the elements in a list, one per line: • Assume you can print the tail of L (i.e. printList(L.tl())), so how do you print L?
Example: printing lists (cont.) static void printList (IntList L) { if (!L.empty()) { System.out.println(L.hd()); printList(L.tl()); } }
Example: printing lists (cont.) Print all the elements in a list, all on one line, separated by a comma and a space: • Assume you can print the tail of L (i.e. printList(L.tl())), so how do you print L? • Answer: print L.hd(), followed by a comma and space, but only if the tail of L is non-empty.
Example: printing lists (cont.) static void printList (IntList L) { if (L.empty()) return; else if (L.tl().empty())) System.out.print(L.hd()); else { System.out.print(L.hd()); System.out.print(“, “); printList(L.tl()); } }
Example: addtoend The method can be defined recursively. It adds the integer i at the end of the list L. For example, if L is the list 3, 5, 7, then addtoend(L, 2) returns the list 3, 5, 7, 2. We will see how to define addtoend in the next class, but we can use it for ... IntList addtoend (IntList L, int i)
Example: reading integers • Given integer n, read n integers from the user and place them in a list. • Assume you can read n-1 integers and place them in a list; how can you read n integers? • Answer: read the n-1 integers, creating a list L, then read one more integer and place it at the end of L.
Example: reading integers (cont.) static IntList readList (int n) { if (n == 0) return IL.nil; else { IntList L = readList(n-1); int i = Keyboard.readInt(); return addtoend(L, i); } }