Presentation is loading. Please wait.

Presentation is loading. Please wait.

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)

Similar presentations


Presentation on theme: "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)"— Presentation transcript:

1 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.org 1 Handout: notes Computer Science 61B Data Structures and Advanced Programming Lists and Iterators Lecture 14

2 CS61B L13 Lists (2)Garcia / Yelick Fall 2003 © UCB Review of List Structure public 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

3 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

4 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); } }

5 CS61B L13 Lists (5)Garcia / Yelick Fall 2003 © UCB Methods on a Simple List Class public 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; }

6 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 = size() */ public void add (int n, Object obj) { if (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) } }

7 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 24810 x Doesn’t work for n=0, because no node at -1 6

8 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 previous If loop/control is complicated, consider a sentinel.

9 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 size ( )) { throw new IllegalArgumentException ("out of range: " + n); } else { ListNode node = myHead.ptrTo (n); node.myNext = new ListNode (obj, node.myNext); mySize++; } }

10 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(n 2 ) n k=1

11 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

12 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

13 CS61B L13 Lists (13)Garcia / Yelick Fall 2003 © UCB Enumerations on Lists private 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; }

14 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

15 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).

16 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?

17 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 myPrev X

18 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

19 CS61B L13 Lists (19)Garcia / Yelick Fall 2003 © UCB Code for Iterator with Remove // Also in the class public 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--; }

20 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

21 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.

22 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. ABC 1: FFF 2: FFT 3: FTF 4: TFF 5: FTT 6: TFT 7: TTF 8: TTT What is the veracity of these statements?

23 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; }

24 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

25 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, = medium, L= low) E.g.,: LOVED it, 60% finished, Push: H6 1: 10% 2: 20% 3: 30% … 8: 80% 9: 90% 0: FIN


Download ppt "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)"

Similar presentations


Ads by Google