Sequences and Iterators 2004 Goodrich Tamassia Sequences and

  • Slides: 17
Download presentation
Sequences and Iterators © 2004 Goodrich, Tamassia Sequences and Iterators 1

Sequences and Iterators © 2004 Goodrich, Tamassia Sequences and Iterators 1

6. 3 Iterators Introduction Consider the problem of printing out the elements in a

6. 3 Iterators Introduction Consider the problem of printing out the elements in a collection, represented as an array V. So, its contents are easily printed with code like the following: for (int i = 0; i < V. length; i++) system. out. println (V[i]); In this loop, i is an iterator object, because it is used to control the iteration. However, using the integer i as an iterator constrains the design: We can only store the collection in an array-like structure. A more flexible alternative is to design an iterator class (object) that encapsulates a position inside a collection. An iterator object controls iteration of a collection of elements (e. g, array-list, or sequence). © 2004 Goodrich, Tamassia Sequences and Iterators 2

6. 3. 1 The Iterator ADT An iterator is a software design pattern that

6. 3. 1 The Iterator ADT An iterator is a software design pattern that abstracts the process of scanning through a collection of elements one element at a time. An iterator consists of: n n n A sequence S; A current element in S; and A way of stepping to the next element in S, making it the current element. Thus, an iterator extends the concept of the position ADT, introduced before. In fact, a position can be thought of as an iterator that doesn’t go anyway. An iterator encapsulates the concepts of “place” and “next” in a collection of objects. © 2004 Goodrich, Tamassia Sequences and Iterators 3

The Iterator ADT (Cont. ) An iterator abstracts the process of scanning through a

The Iterator ADT (Cont. ) An iterator abstracts the process of scanning through a collection of elements Methods of the object iterator ADT: n n n object element() to get data or object stored at that position Boolean has. Next() Test whethere are elements left in the iterator object next() Return the next element in the iterator extends the concept of position by adding a traversal capability Implementation can be with an array, singly- or doubly- linked list © 2004 Goodrich, Tamassia Sequences and Iterators 4

The Iterator ADT (Cont. ) Note that the iterator ADT has the cursor notion

The Iterator ADT (Cont. ) Note that the iterator ADT has the cursor notion of the “current” element in a traversal of a sequence. The first element in an iterator is returned by the first call to the method next() , assuming that the iterator contains at least one element. Advantages of iterator ADT An iterator provides a unified scheme to access all the elements of a collection of objects, independently of the specific organization of the collection. An iterator for an array list, node list, or sequence should return the elements according to their linear ordering. © 2004 Goodrich, Tamassia Sequences and Iterators 5

The Iterable Abstract Data Type In order to provide a unified generic mechanism for

The Iterable Abstract Data Type In order to provide a unified generic mechanism for scanning through a data structure, ADTs storing collections of objects should support the following method: iterator(): Return an iterator of the elements in the collection. This method is supported by the java. util. Array. List class. This method can make it simple for us to specify computations that need to loop through the elements of a list. To guarantee that a node list supports this method, for example, we could add this method to the Position. List interface, as shown below: © 2004 Goodrich, Tamassia Sequences and Iterators 6

Public interface Position. List<E> extends Iterable<E> { //… all the other methods of the

Public interface Position. List<E> extends Iterable<E> { //… all the other methods of the list ADT… /* Returns an iterator of all the elements in the list. */ Public Iterator<E> iterator(); } § We assume that our array lists and node lists support the iterator() method. § Given such a Position. List definition, we could use an iterator to create a string representation of a node list, as shown below: /** Returns a textual representation of a given node list */ Public static <E> Stringto. String (Position. List <E> ) l) { Iterator<E> it = l. iterator(); String s = “[“; while (it. has. Next()) { s += it. Next(); // implicit cast of the next element to String if (it. has. Next()) { s += “ , “; } s += “]”; return s; } © 2004 Goodrich, Tamassia Sequences and Iterators 7

6. 3. 3 Implementing Iterators An iterator is typically associated with another data structure

6. 3. 3 Implementing Iterators An iterator is typically associated with another data structure We can augment the Stack, Queue, Vector, Node List and Sequence ADTs with method: n Object Iterator elements() Two ways of implementation of iterator: a. Snapshot: freezes the contents of the data structure at a given time b. Dynamic: follows changes to the data structure © 2004 Goodrich, Tamassia Sequences and Iterators 8

a. Snapshot Method One way to implement an iterator for a collection of elements

a. Snapshot Method One way to implement an iterator for a collection of elements is to make a ‘snapshot’ of it and iterate over it. This approach would involve storing the collection in a separate data structure that supports sequential access to its elements. For example, we could insert (freeze) all the elements of the collection into a queue, in which case: n n Method has. Next() corresponds to !is. Empty() Method next() corresponds to dequeue() With this approach, the method iterator() takes O(n) time for a collection of size n. Since this copying process is costly, we prefer to have iterators operate on the collection itself, not a copy of it. © 2004 Goodrich, Tamassia Sequences and Iterators 9

b. Direct Approach In this method of implementing an iterator , we need only

b. Direct Approach In this method of implementing an iterator , we need only to keep track of where in the collection the iterator’s cursor points. Thus, creating a new iterator in this case simply involves creating an iterator object that represents a cursor placed just before the first element of the collection. Performing the next() method would return the next element, if it exists, and moving the cursor just after this element’s position. Thus, in this implementation way, creating an iterator takes O(1) time, as do each of the iterator’s methods. © 2004 Goodrich, Tamassia Sequences and Iterators 10

6. 4. 3 Sequences A sequence is an ADT that supports all of the

6. 4. 3 Sequences A sequence is an ADT that supports all of the methods of the deque ADT, the Array-List ADT (or, vector), and the Node-List ADT. That is, a sequence provides explicit access to the elements in the list either by their indices or by their positions. Methods of a sequence ADT include: Generic methods: n size(), is. Empty() Vector-based methods: n get(i), set(i, e), add(i, e), remove (i) © 2004 Goodrich, Tamassia Sequences and Iterators 11

Sequences (Cont. ) Node List-based methods: n n first(), last(), prev(p), next(p), set(p, e),

Sequences (Cont. ) Node List-based methods: n n first(), last(), prev(p), next(p), set(p, e), add. Before(p, e), add. After(p, e), add. First(e), add. Last(e), remove(p) Since sequence provides this dual access capability, we also include, in the sequence ADT, the following two “bridging” methods that provide connections between indices and positions: Bridge methods: n at. Index(i) : n index. Of(p) : © 2004 Goodrich, Tamassia Returns the position of the element with index i; an error condition occurs if i < 0 or i > size() -1. Return the index of the element at position p. Sequences and Iterators 12

Multiple Inheritance in the Sequence ADT The definition of the sequence ADT as including

Multiple Inheritance in the Sequence ADT The definition of the sequence ADT as including all the methods from three different ADTs is an example of multiple inheritance. That’s, the sequence ADT inherits methods from the three “super” abstract data types. In other words, its methods include the union of the methods of these three “super” ADTs. © 2004 Goodrich, Tamassia Sequences and Iterators 13

Applications of Sequences The Sequence ADT is a basic, generalpurpose, data structure for storing

Applications of Sequences The Sequence ADT is a basic, generalpurpose, data structure for storing an ordered collection of elements Direct applications: n n Generic replacement for stack, queue, vector, or list small database (e. g. , address book) Indirect applications: n Building block of more complex data structures © 2004 Goodrich, Tamassia Sequences and Iterators 14

Linked List Implementation of a Sequence A doubly linked list provides a reasonable implementation

Linked List Implementation of a Sequence A doubly linked list provides a reasonable implementation of the sequence ADT Nodes implement Position and store: n n n element link to the previous node link to the next node Special trailer and header nodes Position-based methods run in constant time Index-based methods require searching from header or trailer while keeping track of indices; hence, run in linear time nodes/positions header trailer elements © 2004 Goodrich, Tamassia Sequences and Iterators 15

Array-based Implementation of a Sequence elements We use a circular array S storing positions

Array-based Implementation of a Sequence elements We use a circular array S storing positions A position object stores: n n Element Index 0 Indices f and l keep track of first and last positions 1 2 3 positions S f © 2004 Goodrich, Tamassia Sequences and Iterators l 16

Sequence Implementations Operation size, is. Empty at. Index, index. Of, get first, last, prev,

Sequence Implementations Operation size, is. Empty at. Index, index. Of, get first, last, prev, next Array 1 1 1 List 1 n 1 Set(p, e) Set(i, e) Add(i, e), remove(i) add. First, add. Last add. After, add. Before Remove(p) 1 1 n n 1 1 1 © 2004 Goodrich, Tamassia Sequences and Iterators 17