Chapter 6: The Stack Abstract Data Type

Slides:



Advertisements
Similar presentations
0 of 37 Stacks and Queues Lecture of 37 Abstract Data Types To use a method, need to know its essentials: signature and return type o additionally,
Advertisements

Stacks, Queues, and Deques. 2 A stack is a last in, first out (LIFO) data structure Items are removed from a stack in the reverse order from the way they.
Elementary Data Structures CS 110: Data Structures and Algorithms First Semester,
CS 106 Introduction to Computer Science I 12 / 06 / 2006 Instructor: Michael Eckmann.
Unit 11 1 Unit 11: Data Structures H We explore some simple techniques for organizing and managing information H This unit focuses on: Abstract Data Types.
1 Lecture 24 Abstract Data Types (ADT) –I Overview  What is an Abstract Data type?  What is Stack ADT?  Stack ADT Specifications  Array Implementation.
CHAPTER 6 Stacks Array Implementation. 2 Stacks A stack is a linear collection whose elements are added and removed from one end The last element to be.
CHAPTER 6 Stacks. 2 A stack is a linear collection whose elements are added and removed from one end The last element to be put on the stack is the first.
Stacks, Queues, and Deques
Stacks, Queues, and Deques. A stack is a last in, first out (LIFO) data structure –Items are removed from a stack in the reverse order from the way they.
Stacks, Queues, and Deques
Topic 3 The Stack ADT.
Implementing Stacks Ellen Walker CPSC 201 Data Structures Hiram College.
Chapter 3 Introduction to Collections – Stacks Modified
Chapter 7 Stacks. © 2004 Pearson Addison-Wesley. All rights reserved 7-2 The Abstract Data Type: Developing an ADT During the Design of a Solution Specifications.
© 2004 Goodrich, Tamassia Stacks. © 2004 Goodrich, Tamassia Stacks2 Abstract Data Types (ADTs) An abstract data type (ADT) is an abstraction of a data.
CSE 12 – Basic Data Structures Cynthia Bailey Lee Some slides and figures adapted from Paul Kube’s CSE 12 CS2 in Java Peer Instruction Materials by Cynthia.
1 Chapter 7 Stacks and Queues. 2 Stack ADT Recall that ADT is abstract data type, a set of data and a set of operations that act upon the data. In a stack,
CSE 373: Data Structures and Algorithms Lecture 1: Introduction; ADTs; Stacks; Eclipse.
30 May Stacks (5.1) CSE 2011 Winter Stacks2 Abstract Data Types (ADTs) An abstract data type (ADT) is an abstraction of a data structure An.
© 2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved. Data Structures for Java William H. Ford William R. Topp Chapter 13 Implementing.
CSC 212 – Data Structures Lecture 17: Stacks. Question of the Day Move one matchstick to produce a square.
Chapter 6 Stacks. Copyright © 2004 Pearson Addison-Wesley. All rights reserved.1-2 Chapter Objectives Examine stack processing Define a stack abstract.
1 Linked-list, stack and queue. 2 Outline Abstract Data Type (ADT)‏ Linked list Stack Queue.
Copyright © 0 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with Java From Control Structures through Data Structures by Tony.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Data Structures in Java: From Abstract Data Types to the Java Collections.
1 Stacks (Continued) and Queues Array Stack Implementation Linked Stack Implementation The java.util.Stack class Queue Abstract Data Type (ADT) Queue ADT.
Lecture Objectives  To understand how Java implements a stack  To learn how to implement a stack using an underlying array or linked list  Implement.
“The desire for safety stands against every great and noble enterprise.” – Tacitus Thought for the Day.
CSE 373 Data Structures and Algorithms Lecture 1: Introduction; ADTs; Stacks; Eclipse.
M180: Data Structures & Algorithms in Java Stacks Arab Open University 1.
Click to edit Master text styles Stacks Data Structure.
Chapter 3: Fundamental Data Structures: The Array and Linked Structures Data Structures in Java: From Abstract Data Types to the Java Collections Framework.
Chapter 8: Recursion Data Structures in Java: From Abstract Data Types to the Java Collections Framework by Simon Gray.
Stack: a Linked Implementation
Chapter 5: The List Abstract Data Type
Elementary Data Structures
Comprehensive Introduction to OOP with Java, C. Thomas Wu Stack ADT
CSE 373 Implementing a Stack/Queue as a Linked List
Stacks The content for these slides was originally created by Gerard Harrison. Ported to C# by Mike Panitz.
Marcus Biel, Software Craftsman
Chapter 6: The Stack Abstract Data Type
Stacks.
Queues Queues Queues.
The Stack ADT. 3-2 Objectives Define a stack collection Use a stack to solve a problem Examine an array implementation of a stack.
CSE 373: Data Structures and Algorithms
Building Java Programs Chapter 14
COMPUTER 2430 Object Oriented Programming and Data Structures I
Introduction to Data Structures
Stacks and Queues.
Stack ADT & Modularity 2 implementations of the Stack abstract data type: Array Linked List Program design: modularity, abstraction and information hiding.
Stacks.
Stacks, Queues, and Deques
Stacks and Queues.
Stacks, Queues, and Deques
Building Java Programs
Building Java Programs
Programming II (CS300) Chapter 07: Linked Lists and Iterators
Stacks and Queues CLRS, Section 10.1.
COMPUTER 2430 Object Oriented Programming and Data Structures I
Cs212: Data Structures Computer Science Department Lecture 6: Stacks.
Stacks.
More Data Structures (Part 1)
Stacks Chapter 5.
Chapter 5 Stack (part 1).
Programming II (CS300) Chapter 07: Linked Lists
Stacks, Queues, and Deques
Stacks and Queues.
CMPT 225 Lecture 7 – Stack.
CHAPTER 3: Collections—Stacks
Presentation transcript:

Chapter 6: The Stack Abstract Data Type Data Structures in Java: From Abstract Data Types to the Java Collections Framework by Simon Gray

Introduction Examples of Stack usage: Browser “back” button: takes you to the page visited before the current page Editor “undo” button: takes you to the state of the document before the current state Process stacks: stores call frames to support method calls. The call frame on top of the stack is the currently executing method, the call frame below it represents the method invoked before the current method, and so on Stack: a Last-In-First-Out (LIFO) data structure – the last item into the stack is the first out of it Attributes: top – references the element on top of the stack Operations: push(element), pop(), peek(), isEmpty(), size()

Stack Properties and Attributes Stacks are LIFO data structures. All accesses are done to the element referenced by top. The top always refers to the topmost element in the stack. Insertions are done “above” the top element. Attributes size : The number of elements in the stack: size >= 0 at all times. top : The topmost element of the stack, refers to null, a special value indicating top doesn’t reference anything in the stack.

Stack Operations Stack() pre-condition: none responsibilities: constructor – initialize the stack attributes post-condition: size is 0 top refers to null (a special value not part of the stack) returns: nothing push( Type ) responsibilities: push element onto the top of the stack post-condition: element is placed on top of the stack size is incremented by 1 top refers to the element pushed

Stack Operations pop() pre-condition: isEmpty() is false responsibilities: remove and return the element at top post-condition: the top element is no longer in the stack size is decremented by 1 top refers to the element below the previous topmost element or null if the stack is empty returns: the element removed throws: empty stack exception if pre-condition is not met

Stack Operations peek() pre-condition: isEmpty() is false responsibilities: return the element at top post-condition: the stack is unchanged returns: the element referenced by top throws: empty stack exception if pre-condition is not met

Behavior of Stack’s operations Method Purpose Object State Returned Value Stack<String> s = new LinkedStack<String>() Create an empty stack s size = 0 top = null a LinkedStack object for Strings s.push (“A”) Add“A” to stack s size = 1 “A” top s.push (“B”) Add “B” to stack s size = 2 “A” “B” String str = s.peek() Peek at the top element of stack s “B” str = s.pop() Pop top element from stack s s.isEmpty() See if the stack s is empty false true str = s.peek() exception

Designing a Test Plan Ask questions! What are the bounds for this collection type? empty? full? not empty and not full? one element? one element away from being full? (off-by-1checks!) How does each operation change the state of the stack? Should come from operations description and pre-conditions – the specification is important! What are the invalid conditions that must be caught? Should come from operations pre-conditions and throws descriptions Designing test cases helps clarify the specification. You can’t start coding until you are clear about the behavior of the operations!

Test Case 6.2: Pushing onto a Stack Method Purpose Object State Expected Result Stack<String> s = new ListStack<String>() Create an empty stack size = 0 top = null position a ListStack for Strings s.push(“www.nps.gov”) Push onto an empty stack size = 1 top = “www.nps.gov” s.size() Verify new stack state 1 s.isEmpty() false String str = s.peek() “www.nps.gov” s.push(“www.nasa.gov”) Push onto a non-empty stack size = 2 top = “www.nasa.gov” www.nps.gov” 2 str = s.peek() “www. nasa.gov” s.push(“www.bls.gov”) size = 3 top = “www.bls.gov” “www.nasa.gov” 3 str = s.peek() “www.bls.gov”

Adapter Design Pattern Problem: Need to create a class that implements the API defined in an interface we are given. We know of an existing class that offers some or all of the functionality described by the target interface we need to implement, but the existing class has a different API

Adapter Design Pattern: Description The Adapter design pattern solves this problem by adapting the API of the existing class to that of the target interface. The basic steps are as follows – see the figure on the next slide Define an adapter class, (here called AdapterClass, but the actual name doesn’t matter) that implements the target interface Methods in the target interface are matched with counterparts in the existing class (called ExistingClass here) that provide the same general behavior An instance of ExistingClass is included in AdapterClass through composition The methods in AdapterClass simply forward the message to the corresponding method in ExistingClass. This is called message forwarding

Adapter Design Pattern: UML Diagram

Adapter Design Pattern: Consequences The adapter pattern allows you to quickly implement a new class by reusing an existing class that provides at least some of the behavior needed, but through a different API. This is especially useful for rapid development of prototypes, when execution speed is not an issue There is a performance cost. The indirection introduced by the message forwarding from the AdapterClass object to the ExistingClass object requires additional time The API of ExistingClass is visible only to AdapterClass and is completely hidden from the client

ListStack: Applying the Adapter Pattern Tasks to complete to implement a Stack using a List as the backing store: Determine whether a field from List can take on the responsibility of an attribute or method from Stack Determine which methods from List can provide the behavior defined by methods from Stack Implement the Stack methods using the information gathered in the first two tasks

Map Stack Attributes to List Attributes and/or Methods Remember, an attribute can be stored or synthesized from other information available Stack.size maps nicely to List.size Stack.top – all accesses to a stack are at its top, which we can picture as one end of a linear structure. Where are List accesses most efficient?

Map Stack Attributes to List Attributes and/or Methods List Equivalent top size() – 1 size size() Don’t underestimate the importance of doing this mapping first. Careful planning saves time later!

Map Stack Methods to List Methods A consequence of the attribute mapping is that a push op results in appending to the List size() – 1 + 1 = size() tail of list next position beyond tail location to “push” the new stack element Stack operation List operation equivalent push( element ) add( size(), element ) E pop() E remove( size() - 1 ) E top() E get( size() – 1 ) int size() boolean isEmpty()

ListStack: The UML Diagram Compare this to the UML diagram for the Adapter Design Pattern

What does the implementation look like? 1 package gray.adts.stack; 2 3 import java.util.LinkedList; 4 import java.util.List; 5 import java.util.EmptyStackException; 6 7 /** 8 * An implementation of the Stack interface using a list as the 9 * underlying data structure. 10 */ 11 public class ListStack<E> implements Stack<E> { 12 private java.util.List<E> stack; 13 // the top element of stack is stored at position 14 // s.size() - 1 in the list. 15 16 /** 17 * Create an empty stack. 18 */ 19 public ListStack() { 20 stack = new LinkedList(); 21 } 22 Note the use of comments to help me remember important details The “stack” is really a List; put another way, the stack’s elements will be stored in a List

What does the implementation look like? 23 /** 24 * Determine if the stack is empty. 25 * @return <tt>true</tt> if the stack is empty, 26 * otherwise return <tt>false</tt>. 27 */ 28 public boolean isEmpty() 29 { 30 return stack.isEmpty(); 31 } 32 33 /** 34 * Return the top element of the stack without removing it. 35 * This operation does not modify the stack. 36 * @return topmost element of the stack. 37 * @throws EmptyStackException if the stack is empty. 38 */ 39 public E peek() 40 { 41 if ( stack.isEmpty() ) 42 throw new EmptyStackException(); 43 return stack.get( stack.size() - 1 ) ; 44 } message forwarding – let the List object do all the work Having done the attribute mapping, this is easy to figure out

What does the implementation look like? 46 /** 47 * Pop the top element from the stack and return it. 48 * @return topmost element of the stack. 49 * @throws EmptyStackException if the stack is empty. 50 */ 51 public E pop() 52 { 53 if ( stack.isEmpty() ) 54 throw new EmptyStackException(); 55 return stack.remove( stack.size() - 1 ); 56 } 57 58 /** 59 * Push <tt>element</tt> on top of the stack. 60 * @param element the element to be pushed on the stack. 61 */ 62 public void push( E element) 63 { 64 stack.add( stack.size(), element ); 65 } Compare with peek() List.size() -1 is top, so “push” new element at List.size()

A Linked Implementation of Stack Task list: Decide which linked structure representation to use: singly linked list or doubly linked list Map the Stack ADT attributes to a linked list implementation. In doing this we will identify the data fields our class will need Implement the Stack ADT operations as methods in our class

Singly or Doubly Linked List? How do we decide? What are the salient characteristics of a Stack? All accesses are at the top Don’t need the additional complexity of a doubly linked list  a singly linked list will do

Map Stack ADT attributes to a linked list implementation A linked list is a linear structure. Which end should be the top? Where is it easiest and most efficient to do inserts and deletes? At the head of the linked list top will refer to the head of the linked list Use a dummy node for the head to simplify inserts/deletes at the head  top will refer to a dummy node representing the head of the linked list

Map Stack ADT attributes to a linked list implementation public class LinkedStack<E> implements Stack<E> { private int size; private SLNode<E> top; top: An empty LinkedStack using a dummy node for top top

The push() operation Pushing an element onto an empty stack 1. create a new SLNode (a) 2. Set the new node’s successor field to be the same as top’s next field (b) 3. Set top’s successor field to reference the new node. (c) 4. Increment size by 1 1 public void push( E element ) { 2 3 SLNode newNode = 4 new SLNode<E>(element, 5 top.getSuccessor()); (a, b) 6 7 top.setSuccessor( newNode ); (c) 8 9 size++; 10 } Pushing an element onto an empty stack Steps (a) and (b) Step (c)

The push() operation Pushing an element onto a non-empty stack 1. create a new SLNode (a) 2. Set the new node’s successor field to be the same as top’s next field (b) 3. Set top’s successor field to reference the new node. (c) 4. Increment size by 1 1 public void push( E element ) { 2 3 SLNode newNode = 4 new SLNode<E>(element, 5 top.getSuccessor()); (a, b) 6 7 top.setSuccessor( newNode ); (c) 8 9 size++; 10 } Pushing an element onto a non-empty stack Steps (a) and (b) Step (c)

Implementing the Test Plan One of the advantages of using the Adapter design pattern is that we get to use software that has already been tested, so most of the Stack testing is reduced to seeing that we have used the representation data structure (List) properly. Testing must focus on the associations made between Stack attributes and methods, and how they are represented using the List (e.g., Stack’s top and List’s size() - 1)

Implementing the Test Plan The pop() and peek() operations in Test Case 6.1 should generate exceptions, since trying to look at the top of an empty stack is meaningless. How to do this in JUnit? Use a try-catch block! 1 public void testPopEmpty() { 2 Stack s = new ListStack(); 3 4 try { 5 s.pop(); 6 }catch ( EmptyStackException ex ) { 7 return; // this is what we expect 8 } 9 // if we get here – the test failed :-( 10 fail("testPopEmpty: EmptyStackException expected"); 11 }

Implementation Evaluation Stack Operation List Operation Cost push( element ) add( size(), element ) Ο(1) pop() remove( size() – 1 ) top() get( size() – 1 ) The cost of Stack operations for the Adapter implementation using a List