8 List and Iterator ADTs List concepts List applications A list ADT: requirements, contract ...

48
8 List and Iterator ADTs List concepts List applications A list ADT: requirements, contract Iterators Implementations of lists: using arrays and linked-lists Lists in the Java class library © 2008 David A Watt, University of Glasgow Algorithms & Data Structures (M)

Transcript of 8 List and Iterator ADTs List concepts List applications A list ADT: requirements, contract ...

Page 1: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8List and Iterator ADTs

List concepts

List applications

A list ADT: requirements, contract

Iterators

Implementations of lists: using arrays and linked-lists

Lists in the Java class library

© 2008 David A Watt, University of Glasgow

Algorithms & Data Structures (M)

Page 2: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-2

List concepts (1)

A list is a sequence of elements, in a fixed order. Elements can added/removed at any position.

Elements are in positions 0 (leftmost), 1, 2, ….

The size (or length) of a list is the number of elements.

The concatenation of lists l1 and l2 is a list containing all elements of l1 followed by all elements of l2.

We can traverse a list (or iterate over the list), i.e., visit each of the list’s elements in turn.

Page 3: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-3

List concepts (2)

Mathematical notation for lists:

– «x0, x1, …, xn–1» is a list of length n, whose elements are x0, x1, …, xn–1 (in that order).

– « » is the empty list.

– Note: We can use this notation in algorithms, but it is not supported by Java.

Page 4: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-4

Example: lists and concatenation

A list of integers:

fibonacci = «1, 1, 2, 3, 5, 8, 13, 21, 34»

A list of airports:

tour = «GLA, LHR, CDG, GLA»

Lists of words:

hamlet1 = «‘to’, ‘be’, ‘or’, ‘not’, ‘to’, ‘be’»

hamlet2 = «‘that’, ‘is’, ‘the’, ‘question’»

Concatenation of those lists of words:

«‘to’, ‘be’, ‘or’, ‘not’, ‘to’, ‘be’, ‘that’, ‘is’, ‘the’, ‘question’»

Page 5: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-5

Lists vs linked-lists

Do not confuse the list abstract data type with linked-list data structures.

A list ADT can be implemented using different data structures (arrays, linked-lists).

Conversely, linked-list data structures can be used to implement many different ADTs (e.g., stacks, queues, lists, sets).

Page 6: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-6

List applications

A sentence is a list of words.

– The words are in the order they are read or spoken.

An itinerary is a list of places visited on a tour.

– The places are in the order they are visited.

A log is a list of event records (e.g., equipment faults).

– The event records are in time order.

Page 7: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-7

Example: simple text editor (1)

Consider a very simple text editor that supports insertion and deletion of complete lines only.

The user can load text from a file, or save the text to a file.

The user can select any line of the text:

– directly (by pointing at it, or giving a line number)

– by searching for a line matching a given search string.

The user can delete the selected line.

The user can insert a new line, either above the selected line or below the selected line.

Page 8: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-8

Example: simple text editor (2)

We can represent the text being edited by:

– a list of lines, text

– the position sel of the selected line

We can implement the user commands straightforwardly in terms of list operations, e.g.:

– Delete: remove the line at position sel in text.

– Insert above: add the new line at position sel in text, then increment sel.

– Insert below: increment sel, then add the new line at position sel in text.

– Save: traverse text, writing each line to the output file.

Page 9: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-9

List ADT: requirements

Requirements:

1) It must be possible to make a list empty.

2) It must be possible to test whether a list is empty.

3) It must be possible to obtain the length of a list.

4) It must be possible to add an element at any position in a list.

5) It must be possible to remove the element at any position in a list.

6) It must be possible to inspect or update the element at any position in a list.

7) It must be possible to concatenate lists.

8) It must be possible to test lists for equality.

9) It must be possible to traverse a list.

Page 10: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-10

List ADT: contract (1)

Possible contract for homogeneous lists:

public interface List<E> {

// Each List<E> object is a homogeneous list // whose elements are of type E.

//////////// Accessors ////////////

public boolean isEmpty ();// Return true if and only if this list is empty.

public int size ();// Return this list’s length.

Page 11: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-11

List ADT: contract (2)

Possible contract (continued):

public E get (int p);// Return the element at position p in this list.

public boolean equals (List<E> that);// Return true if and only if this list and that have

the // same length, and each element of this list

equals // the corresponding element of that.

Page 12: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-12

List ADT: contract (3)

Possible contract (continued):

//////////// Transformers ////////////

public void clear ();// Make this list empty.

public void set (int p, E it); // Replace the element at position p in // this list by it.

public void add (int p, E it);// Add it at position p in this list.

public void addLast (E it);// Add it after the last element of this list.

This changes the positions of succeeding elements.

Page 13: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-13

List ADT: contract (4)

Possible contract (continued):

public void addAll (List<E> that);// Add all the elements of that after the// last element of this list.

public E remove (int p);// Remove and return the element at// position p in this list.

//////////// Iterator ////////////

public Iterator<E> iterator ();// Return an iterator that will visit all// elements of this list, in left-to-right order.

}

This changes the positions of succeeding elements.

Page 14: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-14

Traversal (1)

To traverse array:

for (int i = 0; i < array.length; i++)… array[i] …

This traversal has time complexity O(n).

We could mimic this to traverse list:

for (int p = 0; p < list.size(); p++)… list.get(p) …… list.set(p, x) …

But this traversal could have time complexity O(n2), if get and set turn out to be O(n).

Page 15: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-15

Traversal (2)

Better, use an iterator to traverse list:

Iterator<T> elements = list.iterator();

while (elements.hasNext()) {T elem = elements.next();… elem …

}

This traversal has time complexity O(n), since the hasNext() and next() operations are guaranteed to be O(1).

visits the next element in that iterator

tests whether that iterator still has more elements to visit

constructs an iterator over the elements of list

Page 16: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-16

Iterators (1)

View an iterator as a path along which we visit the elements one by one, in some desired order.

Examples of iterators over a list:

‘to’, ‘be’, ‘or’, ‘not’, ‘to’, ‘be’ »«

left-to-right iterator

right-to-left iterator

Page 17: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-17

Iterators (2)

The List interface’s iterator() operation constructs a left-to-right iterator over the list elements.

The iterator’s hasNext() operation tests whether there is a next element still to be visited.

The iterator’s next() operation returns the next element (if any).

Page 18: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-18

Iterator ADT: contract

Java’s contract for iterators:

public interface Iterator<E> {

// Each Iterator<E> object represents an iterator // over some collection of elements of type E.

public boolean hasNext ();// Return true if and only if this iterator has a next // element. Guaranteed O(1).

public E next ();// Return the next element in this iterator. // Guaranteed O(1).

}omitted operation

Page 19: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-19

Iterators: implementation

An iterator is represented by a position on the iterator’s path, typically:

– an index (if the elements are held in an array)

– a link (if the elements are held in a linked-list).

The hasNext() operation tests whether there is a next position on the iterator’s path.

The next() operation advances to the next position on the iterator’s path, and returns the element at that position.

– It throws an exception if there is no next position.

Page 20: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-20

Implementation of lists using arrays (1)

Represent a bounded list (size cap) by:

– a variable size

– an array elems of length cap, containing the elements in elems[0…size–1].

Illustration(cap = 6): LHR CDG GLAGLA

0 1 2 3 5size=4

Empty list:cap–1size=0

elementelement element0 1 size–1 cap–1

Invariant:

last element unoccupiedfirst element

Page 21: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-21

Implementation of lists using arrays (2)

Java implementation:

public class ArrayList<E> implements List<E> {

private E[] elems;private int size;

//////////// Constructor ////////////

public ArrayList (int cap) {elems = (E[]) new Object[cap];size = 0;

}

Page 22: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-22

Implementation of lists using arrays (3)

Java implementation (continued):

//////////// Accessors ////////////

public int size () {return size;

}

public E get (int p) {if (p < 0 || p >= size) throw …;return elems[p];

}

Page 23: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-23

Implementation of lists using arrays (4)

Java implementation (continued):

//////////// Transformers ////////////

public void add (int p, E it) {if (p < 0 || p > size) throw …;if (size == elems.length) …for (int j = size; j > p; j--)

elems[j] = elems[j-1];elems[p] = it;size++;

}

Page 24: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-24

Implementation of lists using arrays (5)

Java implementation (continued):

//////////// Iterator ////////////

public Iterator<E> iterator () {return new LRIterator();

}

//////////// Inner class ////////////

private class LRIteratorimplements Iterator<E> {

…}

}

Page 25: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-25

Implementation of lists using arrays (6)

Implementing iterators over ArrayList objects:

//////////// Inner class ////////////

private class LRIterator implements Iterator<E> {

// An LRIterator object is a left-to-right iterator // over an ArrayList<E> object.

private int position;// position is the index of the slot containing the // next element to be visited.

private LRIterator () {position = 0;

}

Page 26: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-26

Implementation of lists using arrays (7)

Implementing iterators over ArrayList objects (continued):

public boolean hasNext () {return (position < size);

}

public E next () {if (position >= size) throw …;return elems[position++];

}

}

Page 27: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-27

Implementation of lists using arrays (8)

Since LRIterator is a non-static inner class of ArrayList, its instance methods can access ArrayList instance variables. E.g.:

0position

LRIteratorclass

iter iterator constructed byiter = tour.iterator();

LHR CDG GLAGLA0 1 2 3 4

6Object[ ]class length

4size

ArrayListclass elems

tour

5

Page 28: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-28

Implementation of lists using SLLs (1)

Represent an (unbounded) list by:

– a variable size

– an SLL, with links to both first and last nodes.

Invariant:element element element

first element last element

firstlastsize

Empty list:0

firstlastsize

Illustration:GLA LHR CDG GLA

4

firstlastsize

Page 29: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-29

Implementation of lists using SLLs (2)

Java implementation:public class LinkedList<E>

implements List<E> {

private Node first, last;private int size;

//////////// Inner class ////////////

private static class Node {…

}

//////////// Constructor ////////////

public LinkedList () {first = last = null;size = 0;

}

Page 30: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-30

Implementation of lists using SLLs (3)

Java implementation (continued):

//////////// Accessors ////////////

public int size () {return size;

}

public E get (int p) {if (p < 0 || p >= size) throw …;return locate(p).element;

}

Page 31: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-31

Implementation of lists using SLLs (4)

Java implementation (continued):

/////////// Auxiliary method ///////////

private Node locate (int p) {// Return a link to the node at position p in this list.

Node curr = first;for (int j = 0; j < p; j++)

curr = curr.succ;return curr;

}

Page 32: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-32

Implementation of lists using SLLs (5)

Java implementation (continued)://////////// Transformers ////////////

public void add (int p, E it) {if (p < 0 || p > size) throw …;Node newest = new Node(it, null);if (p == 0) {

newest.succ = first; first = newest;

} else {Node pred = locate(p-1);newest.succ = pred.succ;pred.succ = newest;

}if (newest.succ == null)

last = newest;size++;

}

Page 33: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-33

Implementation of lists using SLLs (6)

Java implementation (continued):

//////////// Iterator ////////////

public Iterator<E> iterator () {return new LRIterator();

}

//////////// Inner class ////////////

private class LRIteratorimplements Iterator<E> {

…}

}

Page 34: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-34

Implementation of lists using SLLs (7)

Implementing iterators over LinkedList objects:

private class LRIteratorimplements Iterator<E> {

// An LRIterator object is a left-to-right iterator over

// a LinkedList<E> object.

private Node position;// position is a link to the node containing the

next // element to be visited.

private LRIterator () {position = first;

}

Page 35: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-35

Implementation of lists using SLLs (8)

Implementing iterators over LinkedList objects (continued):

public boolean hasNext () {return (position != null);

}

public E next () {if (position == null) throw …;E nextElem = position.element;position = position.succ;return nextElem;

}

}

Page 36: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-36

Implementation of lists using SLLs (9)

Since LRIterator is a non-static inner class of LinkedList, its instance methods can access LinkedList instance variables:

iterator constructed byiter = tour.iterator();

positionLRIterator

classiter

lastLinkedList

class firsttour 4

size

GLAelement

Nodeclass succ

GLAelement

Nodeclass succ

Page 37: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-37

Summary of list implementations

Time complexities of main operations:

Operation Array representation SLL representation

get O(1) O(p)

set O(1) O(p)

remove O(n) O(p)

add O(n) O(p)

addLast

best

worst

O(1)O(n)

O(1)

equals O(n) O(n)

addAll O(n') O(n')

where n' = size of second list

Page 38: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-38

Iterating over a list with a Java for-loop

The following code pattern is extremely common:

List<T> list;…Iterator<T> elems = list.iterator();while (elems.hasNext()) {

T elem = elems.next();… elem …

}

So Java provides equivalent for-loop notation:

List<T> list;…for (T elem : list) {

… elem …}

Read this as “for each element elem in list, do the following”.

Page 39: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-39

Lists in the Java class library (1)

The library interface java.util.List<E> is similar to the above interface List<E>.

The library class java.util.ArrayList<E> implements java.util.List<E>, representing each list by an array.

The library class java.util.LinkedList<E> implements java.util.List<E>, representing each list by a doubly-linked-list. (Why?)

Page 40: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-40

Lists in the Java class library (2)

Time complexities of the principal list methods:

Method ArrayList LinkedList

get O(1) O(p)

set O(1) O(p)

remove O(n) O(p)

add O(n) O(p)

addLast bestworst

amortized

O(1)O(n)O(1)

O(1)dittoditto

Page 41: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-41

Aside: amortized complexity (1)

An operation’s amortized time complexity reflects its performance averaged over a large number of calls.

Consider the addLast method in ArrayList :

– Normally, only 1 copy is needed.

– When the array is full, n elements are copied into a new array with doubled length, so in total n+1 copies are needed.

Page 42: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-42

Aside: amortized complexity (2)

Consider 30 consecutive additions to an empty list (with initial capacity 4).

Number of copies:

1, 1, 1, 1, 5, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 (total 58)

On average: 2 copies per call.

Amortized time complexity is O(1). 10 20 30

total copies

10

20

30

40

50

00

no. of calls

60

Page 43: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-43

Example: simple text editor again (1)

Outline implementation of the simple text editor:

public class TextEditor {

private List<String> text;private int sel; // position of the selected

line

public TextEditor () {// Make the text empty.

text = new ArrayList<String>();sel = -1;

}

or: new LinkedList<String>()

Page 44: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-44

Example: simple text editor again (2)

Outline implementation (continued):

public void select (int p) {// Select the line at position p.

if (p < 0 || p >= text.size())throw …;

sel = p;}

public void delete () {// Delete the selected line.

if (sel < 0) throw …;text.remove(sel);if (sel == text.size()) sel--;

}

Page 45: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-45

Example: simple text editor again (3)

Outline implementation (continued):public void find (String str) {// Select the next line containing str as a

substring. // Wrap round to line 0 if necessary.

if (sel < 0) throw …;int p = sel, n = text.size();do {

String line = text.get(p);if (line.indexOf(str) >= 0) {// … str found

sel = p; return;}if (++p == n) p = 0;

} while (p != sel);throw …; // str not found

}

Page 46: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-46

Example: simple text editor again (4)

Outline implementation (continued):

public void insertAbove (String line) {// Insert line immediately above the selected line.

if (sel < 0) throw …;text.add(sel, line);sel++;

}

public void insertBelow (String line) {// Insert line immediately below the selected line.

sel++;text.add(sel, line);

}

Page 47: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-47

Example: simple text editor again (5)

Outline implementation (continued):

public void load (BufferedReader input) {

// Load the entire contents of input into the text.for (;;) {

String line = input.readLine();if (line == null) break;text.addLast(line);

}sel = text.size() - 1; // select last line

}

Page 48: 8 List and Iterator ADTs  List concepts  List applications  A list ADT: requirements, contract  Iterators  Implementations of lists: using arrays.

8-48

Example: simple text editor again (6)

Outline implementation (continued):

public void save (BufferedWriter output) {

// Save the text to output.for (String line : text)

output.write(line + "\n");}

}