CSE 373 Implementing a Stack/Queue as a Linked List

Slides:



Advertisements
Similar presentations
CSE 143 Lecture 22: Advanced List Implementation (ADTs; interfaces; abstract classes; inner classes; generics; iterators)
Advertisements

CSE 143 Lecture 7 Stacks and Queues reading: Stuart Reges notes on website slides created by Marty Stepp
CSE 143 Lecture 15 Sets and Maps; Iterators reading: ; 13.2; 15.3; 16.5 slides adapted from Marty Stepp
CSE 373 Data Structures and Algorithms Lecture 2: Queues.
CSE 143 Lecture 7 Stacks and Queues reading: "Appendix Q" (see course website) slides created by Marty Stepp and Hélène Martin
CSE 143 Lecture 5 Stacks and Queues slides created by Marty Stepp
1 Chapter 20 Lists, Stacks, Queues Lecture 7 Dr. Musab Zghoul برمجة هيكلية.
Stacks and Queues. 2 3 Runtime Efficiency efficiency: measure of computing resources used by code. can be relative to speed (time), memory (space), etc.
CSE 143 Lecture 10 Linked List Basics reading: slides created by Marty Stepp
CSE 143 Lecture 24 Advanced collection classes (ADTs; abstract classes; inner classes; generics; iterators) read 11.1, 9.6, , slides.
© 2006 Pearson Addison-Wesley. All rights reserved5 B-1 Chapter 5 (continued) Linked Lists.
CSE 373: Data Structures and Algorithms Lecture 2: Queues.
CSE 143 Lecture 12: Sets and Maps reading:
1 Queues (Continued) Queue ADT Linked queue implementation Array queue implementation Circular array queue implementation Deque Reading L&C , 9.3.
slides adapted from Marty Stepp and Hélène Martin
CSE 143 Lecture 16 Iterators; Grammars reading: 11.1, 15.3, 16.5 slides created by Marty Stepp
Stacks and Queues. 2 Abstract Data Types (ADTs) abstract data type (ADT): A specification of a collection of data and the operations that can be performed.
CSE 143 Lecture 14 Interfaces; Abstract Data Types (ADTs)
Building Java Programs
Building Java Programs Chapter 16
Stacks and Queues.
Linked Lists Chapter 5 (continued)
Building Java Programs
CSE 373: Data Structures and Algorithms
CSE 373: Data Structures and Algorithms
slides created by Marty Stepp
Stacks and Queues.
Building Java Programs Chapter 14
Building Java Programs
Introduction to Data Structures
Building Java Programs
Building Java Programs Chapter 14
Stacks and Queues.
slides created by Marty Stepp
slides created by Marty Stepp and Ethan Apter
Building Java Programs
CSE 143 Lecture 27: Advanced List Implementation
Lecture 26: Advanced List Implementation
slides adapted from Marty Stepp
Building Java Programs
Building Java Programs
Lecture 7: Linked List Basics reading: 16.2
Building Java Programs Chapter 14
Stacks and Queues CLRS, Section 10.1.
slides adapted from Marty Stepp and Hélène Martin
slides created by Marty Stepp and Hélène Martin
slides created by Marty Stepp
CSE 373 Java Collection Framework, Part 2: Priority Queue, Map
Based on slides by Alyssa Harding & Marty Stepp
CSE 143 Lecture 25 Advanced collection classes
Linked Lists Chapter 5 (continued)
CSE 373 Implementing a Stack Reading: Weiss Ch. 3; 3.6; 1.5
slides created by Marty Stepp
Building Java Programs
Generics, Stack, Queue Based on slides by Alyssa Harding
slides created by Marty Stepp
slides adapted from Marty Stepp
Building Java Programs
CSE 143 Lecture 8 Iterators; Comparable reading: 11.2; 10.2
Lecture 7: Linked List Basics reading: 16.2
slides adapted from Marty Stepp
CSE 373 Java Collection Framework reading: Weiss Ch. 3, 4.8
TCSS 143, Autumn 2004 Lecture Notes
slides created by Marty Stepp
CSE 143 Lecture 21 Advanced List Implementation
Linked Lists Chapter 5 (continued)
CSE 373 Set implementation; intro to hashing
Stacks and Queues.
slides created by Marty Stepp
slides created by Marty Stepp and Hélène Martin
Presentation transcript:

CSE 373 Implementing a Stack/Queue as a Linked List Reading: Weiss Ch. 3; 3.7 slides created by Marty Stepp http://www.cs.washington.edu/373/ © University of Washington, all rights reserved.

The Stack<E> ADT We have now implemented a stack using an array. It is also just fine to implement a stack using a linked list. Let's write a LinkedStack class... public interface Stack<E> { void clear(); boolean isEmpty(); E peek(); E pop(); void push(E value); int size(); } public class LinkedStack<E> implements Stack<E> { ...

Recall: linked nodes Each node object stores: public class Node<E> { public E data; public Node next; } Each node object stores: one piece of data a reference to (at least) one other list node Nodes can be "linked" into chains to store a list/stack of values: data next 42 data next -3 data next 17 data next 9 null

Null references null : A value that does not refer to any object. The elements of a new array of objects are initialized to null. Objects' fields are also null by default until initialized. String[] words = new String[5]; private Point myLocation; // null not the same as the empty string "" or the string "null" Why does Java have null? What is it used for? You cannot deference a null variable (use a dot . on it). index 1 2 3 4 value null words

Recall: Linked list Previously you have implemented a linked list. The list is internally implemented as a chain of linked nodes. The LinkedList keeps a reference to its front as a field null is the end of the list; a null front signifies an empty list fast O(1) to add/remove at front, slow O(N) at back (opposite of array) LinkedList front add(value) add(index, value) remove(index) get(index) isEmpty() set(index, value) size() toString() Node Node Node client program never directly interacts with ListNode objects - paint can analogy: LinkedIntList is a painter, the ListNodes are buckets of paint. I don't want the buckets, just do the painting for me! data next 42 data next -3 data next 17 element 0 element 1 element 2

Inner classes // outer (enclosing) class public class name { ... // inner (nested) class private class name { } Only the outer file can see the inner class or make objects of it. Each inner object is associated with the outer object that created it, so it can access/modify that outer object's methods/fields. Usually it makes sense to make your linked Node into an inner class. An inner class sees the generic type parameters (like <E>) of its enclosing outer class, so it should not try to re-declare them.

Implementing push How do we push an element onto the end of a stack? public void push(E value) { Node newNode = new Node(value); newNode.next = front; front = newNode; size++; } s.push(42); // client code front = 42 next data -3 17 element 0 element 1 element 2

Implementing pop How do we pop an element off the end of a stack? public int pop() { int top = front.data; front = front.next; size--; return top; } s.pop(); // client code; returns 42 front = 42 next data -3 17 element 0 element 1 element 2

Queues queue: Retrieves elements in the order they were added. First-In, First-Out ("FIFO") Elements are stored in order of insertion but don't have indexes. Client can only add to the end of the queue, and can only examine/remove the front of the queue. basic queue operations: add (enqueue): Add an element to the back. remove (dequeue): Remove the front element. peek: Examine the front element. front back 1 2 3 analogy: trays of food at the sizzler remove, peek add queue

Queue ADT interface Let's write our own implementation of a queue. As is done in the Java Collection Framework, we will define queues as an ADT by creating a queue interface. public interface Queue<E> { void clear(); boolean isEmpty(); E peek(); E remove(); // remove from back void add(E value); // add to front int size(); }

Implement with array? public class ArrayQueue<E> implements Queue<E> { private E[] elements; private int size; ... A queue is tough to implement efficiently with an unfilled array. The array is fast to add/remove at the end, but slow at the front. queue.add(26); // client code queue.add(-9); queue.add(14); queue.remove(); index 1 2 3 4 5 6 7 8 9 value 26 -9 14 size

Implement with linked list? We could implement a queue as a linked list of nodes. Good idea? problem: fast O(1) to add/remove at front, slow O(N) at back queue needs fast O(1) access to both ends LinkedQueue Node Node Node front add(value) remove() isEmpty() size() toString() client program never directly interacts with ListNode objects - paint can analogy: LinkedIntList is a painter, the ListNodes are buckets of paint. I don't want the buckets, just do the painting for me! data next 42 data next -3 data next 17 element 0 element 1 element 2

Doubly linked list Nodes in a doubly linked list keep references in two directions. The list itself keeps a front and back reference. Fast at both ends! often implemented with "dummy" nodes at each end to avoid nulls Node Node Node prev data next 42 prev data next 42 prev data next 42 element 0 element 1 element 2 client program never directly interacts with ListNode objects - paint can analogy: LinkedIntList is a painter, the ListNodes are buckets of paint. I don't want the buckets, just do the painting for me! prev data next / prev data next / LinkedList front back add(value) remove() ...

Circular array buffer idea: when elements are added/removed from front, rather than shifting, array simply alters its definition of the "front" index. queue.add(26); // client code queue.add(-9); queue.add(14); queue.remove(); // returns 26 queue.remove(); // returns -9 queue.add(87); queue.add(35); index 1 2 3 4 5 6 7 8 9 value 26 -9 14 size front index 1 2 3 4 5 6 7 8 9 value 14 87 35 size front

Iterators iterator: An object that allows a client to traverse the elements of a collection, regardless of its implementation. Remembers a position within a collection, and allows you to: get the element at that position advance to the next position remove the element at that position A common way to examine any collection's elements. "the" "to" "from" "we" set current element: "from" next element: "the" index 1 2 3 value 42 -3 17 29 data next 42 data next -3 data next 17 front current element: -3 current index: 1 current element: -3 current index: 1 iterator iterator

Iterator methods Iterator interface in java.util every collection has an iterator() method that returns an iterator over its elements (usually implemented as an inner class) Set<String> set = new HashSet<String>(); ... Iterator<String> itr = set.iterator(); hasNext() returns true if there are more elements to examine next() returns the next element from the collection (throws a NoSuchElementException if there are none left to examine) remove() removes the last value returned by next() (throws an IllegalStateException if you haven't called next() yet)

Iterator example Set<Integer> scores = new TreeSet<Integer>(); scores.add(94); scores.add(38); // Jenny scores.add(87); scores.add(43); // Marty scores.add(72); ... Iterator<Integer> itr = scores.iterator(); while (itr.hasNext()) { int score = itr.next(); System.out.println("The score is " + score); // eliminate any failing grades if (score < 60) { itr.remove(); } System.out.println(scores); // [72, 87, 94]

Bad linked list usage What's bad about this code? List<Integer> list = new LinkedList<Integer>(); ... (add lots of elements) ... for (int i = 0; i < list.size(); i++) { int value = list.get(i); if (value % 2 == 1) { list.remove(i); } data next 42 data next -3 front = data next 17 element 0 element 1 element 2

Iterators and linked lists Iterators are particularly useful with linked lists. The previous code is O(N2) because each call on get must start from the beginning of the list and walk to index i. Using an iterator, the same code is O(N). The iterator remembers its position and doesn't start over each time. data next 42 data next -3 front = data next 17 element 0 element 1 element 2 current element: -3 current index: 1 iterator

Array stack iterator // Traverses the elements of the stack from top to bottom. private class ArrayStackIterator implements Iterator<E> { private int index; public ArrayStackIterator() { index = size - 1; } public boolean hasNext() { return index >= 0; public E next() { E result = elements[index]; index--; return result; public void remove() { throw new UnsupportedOperationException();

Linked stack iterator // Traverses the elements of the stack from top to bottom. private class LinkedStackIterator implements Iterator<E> { private Node position; // current position in list public LinkedStackIterator() { position = front; } public boolean hasNext() { return position != null; public E next() { E result = position.data; position = position.next; return result; public void remove() { throw new UnsupportedOperationException();

for-each loop and Iterable Java's collections can be iterated using a "for-each" loop: List<String> list = new LinkedList<String>(); ... for (String s : list) { System.out.println(s); } Our collections currently do not work in this way. To fix this, your list must implement the Iterable interface. public interface Iterable<E> { public Iterator<E> iterator(); public class ArrayStack<E> implements Iterable<E> ...

ListIterator lists have a more powerful ListIterator with more methods ListIterator<String> li = myList.listIterator(); lists have a more powerful ListIterator with more methods can iterate forwards or backwards can add/set element values (efficient for linked lists) add(value) inserts an element just after the iterator's position hasPrevious() true if there are more elements before the iterator nextIndex() the index of the element that would be returned the next time next is called on the iterator previousIndex() the index of the element that would be returned the next time previous is called on the iterator previous() returns the element before the iterator (throws a NoSuchElementException if there are none) set(value) replaces the element last returned by next or previous with the given value