introduction to computation and problem solving class 26: linked lists prof. steven r. lerman and...

38
Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Upload: mia-higgins

Post on 27-Mar-2015

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Introduction to Computation and Problem Solving

Class 26: Linked Lists

Prof. Steven R. Lerman and

Dr. V. Judson Harward

Page 2: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

The Java® Collection Classes

• The java.util package contains implementations of many data structures that we are also going to discuss and implement in a simpler way in class. • You are welcome to use the standard Java® implementations in problem sets. They are more elaborate and abstract than the implementations we will develop. • Learning how to implement a few data structures makes you more sophisticated in how you use all data structures. • We will cover the Java® implementations.

2

Page 3: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Lists as an Abstract Data Type

A list is a collection of elements that has a particular order. – It can have arbitrary length. – You should be able to insert or delete an element anywhere. – You should be able to go through the list in order an element at a time.

3

Page 4: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

A List Interface

public interface List { public boolean isEmpty(); public void addFirst( Object o ); public void addLast( Object o ); public boolean contains(Object o); public boolean remove(Object o); public Object removeFirst() throws NoSuchElementException; public void clear(); public int size(); }

4

Page 5: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Lists and Ordinal Position

• There are certain obvious things we would like to do with lists that we can't do using only this interface. Two examples: – How would you access the elements of the list if you did not know them in advance? – How would you insert an item into the list at any other position than the beginning and the end?

• One approach is to number or index the positions in the list.

5

Page 6: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Indexed Lists

• We could then add two methods – public Object get( int n ) throws NoSuchElementException; – public void insert( Object o, int n ) throws NoSuchElementException; • The following code block will traverse an indexed list, myList: for ( int i = 0; i < myList.size(); i++ ) { Object o = myList.get( i ); . . . }

6

Page 7: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Indexed Lists, 2

• Lists implemented using arrays often provide such methods because they are easy to implement. • The idea of using an index to access list members can lead to problems, however. – Since the index depends on ordinal position, it changes every time an item is added to or deleted from the list. – If the list is not implemented on top of an indexed data structure like an array, accessing an indexed element is slow. • When we use large lists like a telephone directory in everyday life, we don't consider the index of an entry, only its relative position.

7

Page 8: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Iterators

• An iterator is a helper class designed to be used with a List or other collection class. • It has methods to return the collection's members one at a time. • Iterators can also implement methods that allow the collection to be modified relative to the current position of the iterator.

8

Page 9: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

ListIterator Interface

public interface ListIterator { public boolean hasNext(); public Object next() throws NoSuchElementException; public void remove() throws IllegalStateException; public void add( Object o ); public void set( Object o ) throws IllegalStateException }

9

Page 10: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Iterator Methods

• The type of iterator we present here returns a new element and advances to the next with the same operation, next(). There is no way to go back using this interface. The Java® ListIterator allows you to go forwards and backwards. • The most recent element returned by next() is the current element. • remove() will delete the current element from the underlying collection. set() will change it. • add() will insert a new element after the current element and before the element that would be returned by the following call to next(). After a call to add(), the inserted element becomes the new current. A call to next() will return the element after the inserted one. • The first call to next() returns the first element of the list.

10

Page 11: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Iterator and its Underlying List

• An iterator is an object based on an underlying collection so we need a way to create an iterator for a collection. • We do this by adding a method to our List interface: public ListIterator listIterator(); • Can you have 2 iterators over the same List?

11

Page 12: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Using an Iterator

List myList = new SLinkedList(); . . . ListIterator iter = myList.listIterator(); . . . while ( iter.hasNext() ) { Object o = iter.next(); . . . }

12

Page 13: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

An Iterator in Action

New Iterator

green

red

purple

orange

current undefined

After 1st call to next()

green

red

purple

orange

current is green

After adding black

green

black

red

purple

orange

current is black

After 2nd call to next()

green

black

red

purple

orange

current is red

13

Page 14: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

An Iterator in Action, 2

After calling remove()

green

black

purple

orange

current is undefined

After 3rd call to next()

green

black

purple

orange

current is purple

14

Page 15: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

List Implementation Stategies

• There are many ways to implement a list. • In array-based implementations like the Java® Vector inserting an element at any place except the end of the list is very expensive because all the elements from the point of insertion until the end must be moved back to make room for the new entry. There is a similar problem with deletion. • For this reason, lists frequently use a linked implementation.

15

Page 16: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Singly Linked Lists

• Linked lists are like freight trains. • Each item to be put on the list is contained in an instance of a new type of object called the link corresponding to a freight car. • In a singly linked list, the link not only contains the listed item, but it also points to the next item in the list as one freight car is coupled to the next. • The last link in the list points to nothing.

16

Page 17: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Singly Linked List Diagram

17

Page 18: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Singly Linked Lists, 2

• The list object itself points to the link holding the first listed item, and often holds an additional reference to the last link of the list to make it easier to append items. • We say that a link “contains” or “points to”, and the list instance “points” or “holds a pointer”. In Java® these are all synonyms for holding a reference. • So the link doesn't really contain the item. It simply holds a reference to the listed item. • The last link holds a null reference in the field that points to the next element.

18

Page 19: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

A Singly Linked List Demonstration

List: List interface Iterator: List iterator interface SLinkedList: List implementation SLinkedListApp: main() application SLinkedListView: List GUI IteratorView: List iterator GUI

19

Page 20: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

The Link Inner Class

public class SLinkedList implements List { private static class SLink { Object item; SLink next;

SLink( Object o, SLink n ) { item = o; next = n; }

SLink( Object o ) { this( o, null ); } } . . .

20

Page 21: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Generic vs. Typed Lists

• The List interface we have specified is general like the Java® Vector class. It stores and retrieves Objects. • If you are writing your own list class, and you know you will only be handling Strings, say, you can replace the Object fields with String fields. For example,

private static class SLink { String item; SLink next; SLink( String o, SLink n ) { item = o; next = n; } SLink( Object o ) { this( o, null ); } }public void addFirst( String o );

21

Page 22: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

The SLinkedList Data Members

• Only first is necessary. • last and length could be found by traversing the list, but having these members and keeping them up to date makes the calls size() and append() much faster.

private int length = 0; private SLink first = null; private SLink last = null;

22

Page 23: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

== vs the Object equals method

• contains( Object o ) and remove( Object o ) must search for Object o in the list. What does it means to find it? • Must the list contain a reference to the identical object (==)? Or is it sufficient that the list contain a reference to an object that is equal but possibly distinct?

static private boolean objectEquals( Object a, Object b ) { if ( a == null ) return ( b == null ); else return a.equals( b ); }

23

Page 24: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Beware the Special Case

• The tricky part about implementing a linked list is not implementing the normal case for each of the methods, for instance, removing an object from the middle of the list. • What's tricky is making sure that your methods will work in the exceptional and boundary cases. • For each method, you should think through whether the implementation will work on – an empty list, – a list with only one or two elements, – on the first element of a list, – on the last element of a list.

24

Page 25: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

removeFirst()

public Object removeFirst() throws NoSuchElementException { if ( first == null ) // if list is empty throw new NoSuchElementException(); else { SLink t = first; first = first.next; // if list had 1 element and is now empty if ( first == null ) last = null; length--; return t.item; } }

25

Page 26: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

removeFirst(), before

26

Page 27: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

removeFirst(), after

27

Page 28: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

removeFirst(), special case

28

Page 29: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

addFirst(Object o)

public void addFirst(Object o) { if ( first == null ) // if the list is empty { first = last = new SLink( o ); } else { first = new SLink( o, first ); } length++; }

29

Page 30: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

addFirst(), before

30

Page 31: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

addFirst(), after

31

Page 32: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

addFirst(), special case

32

Page 33: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Iterator as Inner Class

public ListIterator listIterator() { return new SLinkedListIterator(); }

public class SLinkedListIterator implements ListIterator { . . . }

33

Page 34: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

contains()

public boolean contains(Object o) { ListIterator iter = new SLinkedListIterator(); while ( iter.hasNext() ) { if ( objectEquals( iter.next(), o )) { return true; } } return false; }

34

Page 35: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Linked List Uses and Variations

• Since our List interface possesses append() and removeFirst() methods you can implement a trivial queue on top of the SLinkedList concrete data type. • How would the implementation be changed if each link had a back reference (previous) as well as a forward reference (next)? Such lists are called (you guessed it) doubly linked lists. What operations become easier?

35

Page 36: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

Iterator Caution

Let's carry out a thought experiment. You create and populate a list. You create an iterator over that list. You call removeFirst() on the list to delete the first element of the list. Now call next() on the iterator. What happens? What should happen?

Although our implementation is reasonably robust, iterators assume that they are called over a fixed list. That is, they do NOT guarantee correct results if you modify the list after iterator construction using either list or another iterator instances methods. How might you "fix" this? What does fixing mean? Would it be better to have an iterator that always gave "correct" results or an iterator that threw an exception if the underlying list had been modified?

36

Page 37: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

LinkedList, Exercise

• Download the Java® files from the Lecture 26directory on the class web site and save them to a new directory. Here is a link to the directory.

• Create a new Forte project and add the files to it. Compile and run. SLinkedListApp contains main().

• Play with the simulation. Look at the implementation in SLinkedList and List. The rest of the files manage the simulation. You don't need to look at them unless you are curious. • The addLast and remove buttons don't work because the corresponding method implementations have been removed.

37

Page 38: Introduction to Computation and Problem Solving Class 26: Linked Lists Prof. Steven R. Lerman and Dr. V. Judson Harward

LinkedList, Exercise, 2

• Look at the addFirst() method, and then write addLast(). Beware of special cases (what are they?). • Compile and test using the simulation. • Now look at the contains() method, and then write remove(). Compile and test. • The main List view also has a new red button labelled "double". Click it. It doesn't do anything. Yet. • Clicking the double button calls a method in a new class ListUtil: public static void doubleList( SLinkedList l ) • doubleList() is currently empty. Write an implementation for doubleList() that gets an iterator for the list, l, and doubles each Integer on the list. You will probably want to use the Integer method intValue(). • Compile and test.

38

Java® is a trademark or registered trademark of Sun Microsystems, Inc. in the United States and other countries.