Linked Lists, Stacks and Queues Textbook Sections 3.5 - 3.7 CMSC 341 Linked Lists, Stacks and Queues Textbook Sections 3.5 - 3.7 July 2011 CMSC 341 Lists, Stacks &Queues
Implementing A Linked List To create a doubly linked list as seen below MyLinkedList class Node class LinkedListIterator class Sentinel nodes at head and tail July 2011 CMSC 341 Lists, Stacks &Queues
Empty Linked List An empty double linked list with sentinel nodes. July 2011 CMSC 341 Lists, Stacks &Queues
Inner classes Inner class objects require the construction of an outer class object before they are instantiated. Compiler adds an implicit reference to outer class in an inner class (MyArrayList.this). Good for when you need several inner objects to refer to exactly one outer object (as in an Iterator object). July 2011 CMSC 341 Lists, Stacks &Queues
Nested classes Considered part of the outer class, thus no issues of visibility. Making an inner class private means that only the outer class may access the data fields within the nested class. Is Node a prime candidate for nested or inner class? public or private? Private nested class…. July 2011 CMSC 341 Lists, Stacks &Queues
Implementation for MyLinkedList Class declaration and nested Node class public class MyLinkedList<AnyType> implements Iterable<AnyType> { // Node is a nested class private static class Node<AnyType> public Node( AnyType d, Node<AnyType> p, Node<AnyType> n ) { data = d; prev = p; next = n; } public AnyType data; public Node<AnyType> prev; public Node<AnyType> next; } July 2011 CMSC 341 Lists, Stacks &Queues
2. Data Fields and Accessors private int theSize; //used to help iterator detect changes in List private int modCount = 0; private Node<AnyType> beginMarker; //head node private Node<AnyType> endMarker; //tail node public int size( ){ return theSize; } public boolean isEmpty( ){ return size( ) == 0; July 2011 CMSC 341 Lists, Stacks &Queues
3. Constructor(s) July 2011 CMSC 341 Lists, Stacks &Queues public MyLinkedList( ) { clear( ); } // Changes the size of this collection to zero. public void clear( ) { beginMarker = new Node<AnyType>( null, null,null ); endMarker = new Node<AnyType>( null, beginMarker, null ); beginMarker.next = endMarker; theSize = 0; modCount++; } July 2011 CMSC 341 Lists, Stacks &Queues
4. More Accessors and Mutators public boolean add( AnyType x ) { add( size( ), x ); return true; } public void add( int idx, AnyType x ) { addBefore( getNode( idx ), x ); } public AnyType get( int idx ) { return getNode( idx ).data; } public AnyType set( int idx, AnyType newVal ) { Node<AnyType> p = getNode( idx ); AnyType oldVal = p.data; p.data = newVal; return oldVal; } public AnyType remove( int idx ) { return remove( getNode( idx ) ); } July 2011 CMSC 341 Lists, Stacks &Queues
5. getNode Method private Node<AnyType> getNode( int idx ) { Node<AnyType> p; if( idx < 0 || idx > size( ) ) throw new IndexOutOfBoundsException( ); if( idx < size( ) / 2 ) { p = beginMarker.next; for( int i = 0; i < idx; i++ ) p = p.next; } else { p = endMarker; for( int i = size( ); i > idx; i-- ) p = p.prev; } return p; /** * Gets the Node at position idx, which must range from 0 to size( ). * @param idx index of node being obtained. * @return internal node corresponding to idx. * @throws IndexOutOfBoundsException if idx is not between 0 and size(). */ July 2011 CMSC 341 Lists, Stacks &Queues
6. addBefore Method July 2011 CMSC 341 Lists, Stacks &Queues private void addBefore(Node<AnyType> p, AnyType x) { Node<AnyType> newNode = new Node<AnyType>( x, p.prev, p ); newNode.prev.next = newNode; p.prev = newNode; theSize++; modCount++; } /** * Adds an item to this collection, at specified position p. * Items at or after that position are slid one position higher. * @param p Node to add before. * @param x any object. * @throws IndexOutOfBoundsException if idx is not between 0 and size(),. */ July 2011 CMSC 341 Lists, Stacks &Queues
7. remove and iterator methods private AnyType remove( Node<AnyType> p ) { p.next.prev = p.prev; p.prev.next = p.next; theSize--; modCount++; return p.data; } //required by the Iterable interface public java.util.Iterator<AnyType> iterator( ) { return new LinkedListIterator( ); } /** * Removes the object contained in Node p. * @param p the Node containing the object. * @return the item was removed from the collection. */ July 2011 CMSC 341 Lists, Stacks &Queues
8a. LinkedListIterator class private class LinkedListIterator implements Iterator<AnyType> { private Node<AnyType> current = beginMarker.next; //used to check for modifications to List private int expectedModCount = modCount; private boolean okToRemove = false; public boolean hasNext( ) return current != endMarker; } //continues on next slide… July 2011 CMSC 341 Lists, Stacks &Queues
8b. LinkedListIterator class public AnyType next( ) { if( modCount != expectedModCount ) throw new ConcurrentModificationException( ); if( !hasNext( ) ) throw new NoSuchElementException( ); AnyType nextItem = current.data; current = current.next; okToRemove = true; return nextItem; } //continues on next slide… July 2011 CMSC 341 Lists, Stacks &Queues
8c. LinkedListIterator class public void remove( ){ if( modCount != expectedModCount ) throw new ConcurrentModificationException( ); if( !okToRemove ) throw new IllegalStateException( ); MyLinkedList.this.remove(current.prev); okToRemove = false; ++expectedModCount; } // end of remove Method } // end of LinkedListIterator class }//end of MyLinkedList class July 2011 CMSC 341 Lists, Stacks &Queues
Stacks A restricted list where insertions and deletions can only be performed at one location, the end of the list (top). LIFO – Last In First Out Laundry Basket – last thing you put in is the first thing you remove Plates – remove from the top of the stack and add to the top of the stack July 2011 CMSC 341 Lists, Stacks &Queues
Stack ADT Basic operations are push, pop, and top Stack Model July 2011 CMSC 341 Lists, Stacks &Queues
Adapting Lists to Implement Stacks Adapter Design Pattern Allow a client to use a class whose interface is different from the one expected by the client Do not modify client or class, write adapter class that sits between them In this case, the List is an adapter for the Stack. The client (user) calls methods of the Stack which in turn calls appropriate List method(s). July 2011 CMSC 341 Lists, Stacks &Queues
Adapter Model for Stack Client (Stack user) Stack (adapter) List (adaptee) theStack.push( 10 ) theList.add(0, 10 ) ; July 2011 CMSC 341 Lists, Stacks &Queues
Queues Restricted List Examples Implement as an adapter of List only add to head only remove from tail Examples line waiting for service jobs waiting to print Implement as an adapter of List Implementing a queue could use similar approach to stack want efficient access to both ends could use circular doubly-linked lists July 2011 CMSC 341 Lists, Stacks &Queues
Queue ADT Basic Operations are enqueue and dequeue July 2011 CMSC 341 Lists, Stacks &Queues
Adapter Model for Queue Client (Queue user) theQ.enqueue( 10 ) Queue (adapter) theList.add(theList.size() -1, 10 ) List (adaptee) July 2011 CMSC 341 Lists, Stacks &Queues
Circular Queue Adapter pattern may be impractical Overhead for creating, deleting nodes Max size of queue is often known A circular queue is a fixed size array Slots in array reused after elements dequeued July 2011 CMSC 341 Lists, Stacks &Queues
Circular Queue Data A fixed size array Control Variables July 2011 arraySize the fixed size (capacity) of the array currentSize the current number of items in the queue Initialized to 0 front the array index from which the next item will be dequeued. back the array index last item that was enqueued Initialized to -1 July 2011 CMSC 341 Lists, Stacks &Queues
Circular Queue Psuedocode void enqueue( Object x ) { if currentSize == arraySize, throw exception // Q is full back = (back + 1) % arraySize; array[ back ] = x; ++currentSize; } Object dequeue( ) { if currentSize == 0, throw exception // Q is empty --currentSize; Object x = array[ front ]; front = (front + 1) % arraySize return x; July 2011 CMSC 341 Lists, Stacks &Queues
Circular Queue Example 0 1 2 3 4 5 Trace the contents of the array and the values of currentSize, front and back after each of the following operations. 1. enqueue( 12 ) 7. enqueue( 42 ) 2. enqueue( 17 ) 8. dequeue( ) 3. enqueue( 43 ) 9. enqueue( 33 ) 4. enqueue( 62 ) 10. enqueue( 18 ) 5. dequeue( ) 11. enqueue( 99 ) 6. dequeue( ) July 2011 CMSC 341 Lists, Stacks &Queues