CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29 Dan Garcia (ddgarcia) Kathy Yelick ...

25
CS61B L13 Lists (1) Garcia / Yelick Fall 2003 © U 2003-09-29 Dan Garcia (www.cs.berkeley.edu/~ddgarcia) Kathy Yelick (www.cs.berkeley.edu/~yelick) inst.eecs.berkeley.edu/~cs61b/ www.ucwise.org 1 Handout: notes Computer Science 61B Data Structures and Advanced Programming Lists and Iterators Lecture 14

description

CS61B L13 Lists (3)Garcia / Yelick Fall 2003 © UCB Encapsulation of Lists The inner ListNode class forms the structure We encapsulate the structure, because: –To preserve invariants on the structure, such as absence of cycles –Without it, the empty list is null, which is not an object  can’t ask a list whether it is empty –Without it, you cannot add to the front of the list, if “this” is itself the first node in the list –We can speed up some operations, like size, by adding extra variables (memoizing) –Manipulating pointers is very error-prone, so we only want to write this stuff once and re-use it

Transcript of CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29 Dan Garcia (ddgarcia) Kathy Yelick ...

Page 1: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (1) Garcia / Yelick Fall 2003 © UCB

2003-09-29 Dan Garcia (www.cs.berkeley.edu/~ddgarcia)

Kathy Yelick (www.cs.berkeley.edu/~yelick)

inst.eecs.berkeley.edu/~cs61b/www.ucwise.org1 Handout: notes

Computer Science 61BData Structures and Advanced Programming

Lists and Iterators Lecture 14

Page 2: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (2) Garcia / Yelick Fall 2003 © UCB

Review of List Structurepublic class SimpleList { // private fields in List private int mySize; private ListNode myHead;

private class ListNode { public Object myItem; public ListNode myNext;

public ListNode (Object obj) { myItem = obj; myNext = null;

} public ListNode (Object obj, ListNode next) { myItem = obj; myNext = next; } }}

Inner class

Page 3: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (3) Garcia / Yelick Fall 2003 © UCB

Encapsulation of Lists• The inner ListNode class forms the structure• We encapsulate the structure, because:

– To preserve invariants on the structure, such as absence of cycles

– Without it, the empty list is null, which is not an object can’t ask a list whether it is empty

– Without it, you cannot add to the front of the list, if “this” is itself the first node in the list

– We can speed up some operations, like size, by adding extra variables (memoizing)

– Manipulating pointers is very error-prone, so we only want to write this stuff once and re-use it

Page 4: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (4) Garcia / Yelick Fall 2003 © UCB

A Recursive Helper• Define a method within the ListNode class /** Find the node at the given position * @requires this is acyclic * @param pos is the position to find * @return the node at the given position. * @exception NoSuchElementException if pos < 0 or * pos >= #nodes in this */ public ListNode ptrTo (int pos) { if (position < 0) { throw new NoSuchElementException (“at " + pos); } else if (position == 0) { return this; } else if (myNext == null) { throw new NoSuchElementException (“at " + pos); } else { return myNext.ptrTo (position-1); } }

Page 5: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (5) Garcia / Yelick Fall 2003 © UCB

Methods on a Simple List Classpublic class SimpleList {

public SimpleList ( ) { // ListNode not shown mySize = 0; myHead = null;

}

public int size ( ) { return mySize; }

public void insertFront (Object obj) { myHead = new ListNode (obj, myHead); mySize += 1; } public Object nth (int position) { return myHead.ptrTo (position).myItem; }

private int mySize; private ListNode myHead;

}

Page 6: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (6) Garcia / Yelick Fall 2003 © UCB

Can add at 1 past end

An Add (at position) Method• A method to add at a given position in the

list /** Insert an object at position n * @param n is the position * @param obj is the object to add * @modifies this * @exception IllegalArgumentException if * n < 0 || n >= size() */ public void add (int n, Object obj) { if (n < 0 || n > size ( )) { throw new IllegalArgumentException (“Add…”);

} else { Idea: use ptrTo to get the node before position

link in the new node on the myNext field Two cases: 1) adding to the beginning 2) adding to the middle (or end) }}

Page 7: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (7) Garcia / Yelick Fall 2003 © UCB

Adding a Node• The missing code for n>= 1:

myHead.ptrTo(n-1).myNext = new ListNode (obj, node.myNext);

• Example: add(2, new Integer(6)) myHead.ptrTo(2-1) myHead

2 4 8 10

x

• Doesn’t work for n=0, because no node at -1

6

Page 8: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (8) Garcia / Yelick Fall 2003 © UCB

Sentinels• One solution is to have two cases in the

code (n == 0 and n > 0):– The right approach if your only problem is add– But you end up with these cases in many methods

• A sentinel is an extra element of a list or vector used to protect the others:– It does not hold user data– Its data is not in the abstraction function (toString)

• Common uses:– Put a sentinel at the end to use as stopping criterion

and avoid null check– Put a sentinel at the beginning so every “real” node

has a previousIf loop/control is complicated, consider a sentinel.

Page 9: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (9) Garcia / Yelick Fall 2003 © UCB

Add with Sentinel Node• Put a sentinel node at the front: public SimpleList ( ) { mySize = 0; myHead = new ListNode(null,null);

}public Object nth (int position) { return myHead.ptrTo (position+1).myItem; }

public void add (int n, Object obj) { if (n < 0 || n > size ( )) { throw new

IllegalArgumentException ("out of range: " + n); } else {

ListNode node = myHead.ptrTo (n); node.myNext = new ListNode (obj, node.myNext); mySize++; }

}

Page 10: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (10) Garcia / Yelick Fall 2003 © UCB

Performance of SimpleList• This is a nice clean abstraction, but given a

list lst, how does the following perform?for (int i = 0; i < lst.size(); i++) { System.out.println(lst.nth());}

• Cost of nth on an n-element list (if we know nothing about the position passed in) is O(n), proportional to n

• Count # ListNodes touched in each iteration: 2 + 3 + 4 + … + n + (n+1) = n + k = n + n*(n+1)/2 which is O(n2)

nk=1

Page 11: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (11) Garcia / Yelick Fall 2003 © UCB

Why n*(n+1)/2 ?• What is the sum of the numbers from 1 to

n?• We want to find S in: S = 1 + 2 + 3 + ... + n-1 + n• Can also write this as S = n + n-1 + n-2 + ... + 2 + 1 • Add them to get 2*S = n+1 + n+1 + n+1 + ... + n+1 + n+1 = n*(n+1)• So S = n*(n+1)/2• Alternate proof by area in the G&T book

Page 12: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (12) Garcia / Yelick Fall 2003 © UCB

Making (some) List Accesses O(1)

• Finding an arbitrary element in a list is O(n); there is nothing we can do about that

• But finding the next element in a list is O(1);– give the user this ability without exposing internals

• Enumerations can do this:– Variable to hold ListNode whose item was just returned– The elements method returns a new Enumeration

myHead

9 12 6

Page 13: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (13) Garcia / Yelick Fall 2003 © UCB

Enumerations on Listsprivate class ListEnumeration implements Enumeration { public ListEnumeration ( ) { myPosition = myHead; } public boolean hasMoreElements ( ) { return myPosition != null

&& myPosition.myNext != null; } public Object nextElement ( ) { if (!hasMoreElements ( )) { throw new

NoSuchElementException ("List Enum ran out!"); } myPosition = myPosition.myNext;

return myPosition.myItem; } // myPosition is the element just returned by next private ListNode myPosition;}

Page 14: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (14) Garcia / Yelick Fall 2003 © UCB

Enumerations vs. Iterators• In Java 1.2 and higher, Iterators usually used in

place of Enumerations:– Adds a mutation operation

» remove()– Better names

» hasMoreElements( ) hasNext( )» nextElement( ) next( )

– Implement Iterator interface rather than Enumeration– Import java.util.Iterator– Change return type of elements to Iterator

• The remove operation can be tricky• Otherwise Iterators are similar to Enumerations

Page 15: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (15) Garcia / Yelick Fall 2003 © UCB

Iterator Interface• Iterator interface in java.util.Iterator:• Method Summary boolean hasNext() Returns true if the iteration has more elements.

Object next() Returns the next element in the iteration.

void remove() Removes from the underlying collection the last element returned by the iterator (optional operation).

Page 16: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (16) Garcia / Yelick Fall 2003 © UCB

Implementing Remove•Given an inner class as before:

private class SimpleListIterator implements Iterator { public SimpleListIterator( ) { … as before …} public boolean hasNext( ) { … as before… } public Object next( ) { … as before… } private ListNode myPosition;}

•Attempted implementation of remove (version 1)public void remove ( ) { if (myPosition != null) { myPosition.myNext = myPosition.myNext.myNext; mySize--; }}

•Which element does this code remove?

Page 17: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (17) Garcia / Yelick Fall 2003 © UCB

myPrev myPosition

null

Implementing Remove• The spec says you should remove the element just

returned from next• Keep a pointer to the node before the one to remove

– To remove 9, need a pointer to node with 6– Call this: myPrev (red sleeve in picture, points to ListNode)– Set in Iterator constructor and next

myHead

9 12 6

myPrev myPosition myPositionmyPrev

X

Page 18: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (18) Garcia / Yelick Fall 2003 © UCB

Code for Iterator with Remove

private class SimpleListIterator implements Iterator { public SimpleListIterator ( ) { myPosition = myHead;

myPrev = null;} public boolean hasNext ( ) { return myPosition != null && myPosition.myNext != null;} public Object next ( ) { if (!hasNext ( )) { throw new NoSuchElementException ("Iter ran out!"); } myPrev = myPosition;

myPosition = myPosition.myNext; Object obj = myPosition.myItem; return obj;}

private ListNode myPosition; private ListNode myPrev; // to be continued

Remove code on next slide

Page 19: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (19) Garcia / Yelick Fall 2003 © UCB

Code for Iterator with Remove

// Also in the classpublic void remove() {if (myPrev == null) {

throw new IllegalStateException(“next not yet called”); } if (myPosition == null ) { throw new

NoSuchElementException (“Iter ran out!");} else { myPrev.myNext = myPosition.myNext; myPosition = myPosition.myNext; mySize--;

}}

Page 20: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (20) Garcia / Yelick Fall 2003 © UCB

Interfaces and Missing Method• It doesn’t always make sense to implement

every method in an interface

• If we didn't want to implement remove, for example:

public void remove ( ) { throw new UnsupportedOperationException( "No remove()"); }

• Java documentation convention: interface API says what methods are optional

Page 21: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (21) Garcia / Yelick Fall 2003 © UCB

Mutation During Iteration•In general, mutating a data structure

while iterating over it is dangerous•Usual conventions:

–Can only mutate with mutation on Iterator, not basic operations on structure (e.g., SimpleList)

–After first mutation, need to quit iterating, I.e., execute a break

–Don’t have multiple iterations going on with the same object, if one will mutate it.

Page 22: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (22) Garcia / Yelick Fall 2003 © UCB

Peer Instruction

A. The remove operation on ListIter is constant time O(1).

B. If remove is called twice in a row, two consecutive elements from the original list will be removed

C. There is no need to write specification for all of the SimpleListIter methods.

ABC1: FFF2: FFT 3: FTF4: TFF5: FTT6: TFT7: TTF8: TTT

What is the veracity of these statements?

Page 23: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (23) Garcia / Yelick Fall 2003 © UCB

Fixing the Iterator• In remove, delete the line: myPosition = myPosition.next• And add to remove: if (myPrev != myPosition.next) { throw new IllegalStateException (“already removed current element”); }• In next add: if (myPrev != myPosition.next) { myPrev = myPosition; }

Page 24: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (24) Garcia / Yelick Fall 2003 © UCB

Administrivia• Reading for Wednesday: Chapter 12• Lab 6: no change in checkoff from previous

labs– Not available yet, but will be soon– Try to get future labs online by Monday at 11am

checkoffs only allowed during current week.• Make sure to read the most current Errata for

proj1

Page 25: CS61B L13 Lists (1)Garcia / Yelick Fall 2003 © UCB 2003-09-29  Dan Garcia (ddgarcia) Kathy Yelick  (yelick)

CS61B L13 Lists (25) Garcia / Yelick Fall 2003 © UCB

Project Peer Instruction

How far into the project are you?Use confidence to measure enjoyment!(H = high, <nothing> = medium, L= low)E.g.,: LOVED it, 60% finished, Push: H6

1: 10%2: 20%3: 30%… …8: 80%9: 90%0: FIN