49
Stacks Chapter 5

Stacks

  • Upload
    saad

  • View
    24

  • Download
    0

Embed Size (px)

DESCRIPTION

Stacks. Chapter 5. Chapter Objectives. To learn about the stack data type and how to use its four methods: push , pop , peek , and empty To understand how Java implements a stack To learn how to implement a stack using an underlying array or a linked list - PowerPoint PPT Presentation

Citation preview

Page 1: Stacks

Stacks

Chapter 5

Page 2: Stacks

Chapter 5: Stacks 2

Chapter Objectives

• To learn about the stack data type and how to use its four methods: push, pop, peek, and empty

• To understand how Java implements a stack• To learn how to implement a stack using an underlying

array or a linked list• To see how to use a stack to perform various

applications, including finding palindromes, testing for balanced (properly nested) parentheses, and evaluating arithmetic expressions

Page 3: Stacks

Chapter 5: Stacks 3

Stack

• Dinner plates at a cafeteria• Spring-loaded “stack” of plates• “Push” a new plate onto the stack• “Pop” an existing plate off of the stack

• Only the top plate is accessible• “Last-In, First-Out”, or LIFO

Page 4: Stacks

Chapter 5: Stacks 4

Stack

• Pez dispenser also uses a stack• Only the top Pez candy can be accessed• Can only extract one item at a time• “Push” candy onto stack• “Pop” candy off of stack

• Only the top candy is accessible, LIFO, etc.

Page 5: Stacks

Chapter 5: Stacks 5

Stack

• Stack might seem to be too restrictive• LIFO• Only one element accessible• Only operations are push, pop, peek, empty

• However, stacks are extremely useful in CS• Simple and useful

• For example, stacks used when executing programs• Used like “scratch paper” to keep track of info

Page 6: Stacks

Chapter 5: Stacks 6

Specification of the Stack Abstract Data Type

• Only the top element of a stack is visible, therefore the number of operations performed by a stack are few

• The only operations available are• Inspect the top element (peek)• Retrieve (and remove) the top element (pop)• Put a new element on the stack (push)• Test for an empty stack (empty)

Page 7: Stacks

Chapter 5: Stacks 7

Specification of the Stack Abstract Data Type (continued)

Page 8: Stacks

Chapter 5: Stacks 8

StackInt<E> Interface

/** Stack is a LIFO data structure */public interface StackInt < E > {

/** Pushes an item onto the top of the stack and returns the item pushed. */

E push(E obj);/** Returns the object at the top of

the stack without removing it. */ E peek();/** Returns the object at the top of the stack

and removes it. */E pop();/** Returns true if the stack is empty;

otherwise, returns false.*/ boolean empty();}

Page 9: Stacks

Chapter 5: Stacks 9

Stack Example

• Suppose we have a stack called names

Alice

BobTrudy

• And we execute names.pop();• What is the return value?• “Trudy” and the stack is

Alice

Bob

Page 10: Stacks

Chapter 5: Stacks 10

Stack Example

• We now have the stack

• And we execute names.push(“Charlie”);• What is the return value? • “Charlie” and stack is

Alice

Bob

Alice

BobCharlie

Page 11: Stacks

Chapter 5: Stacks 11

Stack Example

• We now have the stack

• And we execute names.peek();• What is the return value? • “Charlie” and stack is

Alice

BobCharlie

Alice

BobCharlie

Page 12: Stacks

Chapter 5: Stacks 12

Stack Example

• We now have the stack

• And we execute names.empty(); • What is return value?• Returns false and stack is

Alice

BobCharlie

Alice

BobCharlie

Page 13: Stacks

Chapter 5: Stacks 13

Stack Applications

• We consider two programs that use stacks• Palindrome finder• Parentheses matcher

• First we consider palindrome finder• Palindrome: reads the same in either direction• For example: “level” and “Able was I ere I saw Elba”• Note that we do not ignore spaces and punctuation• So, for example, “never odd or even” not considered a

palindrome for this exercise (but often it is)

Page 14: Stacks

Chapter 5: Stacks 14

Palindrome Finder

• Input: string to be tested• Output: message indicating whether string is a

palindrome or not• How to slove this problem?• Many different ways to solve this…• For example, could create a new string by going from

end to beginning of original string• Then compare new and original strings• If equal, string is a palindrome

• But we want to use a stack!

Page 15: Stacks

Chapter 5: Stacks 15

Palindrome Finder

• Using a stack…• Push characters of original string onto stack• Then pop characters off and append to new string

• Compare new string and original string• If same, then it is a palindrome• Why does this work? • If we push, then pop, it will reverse string

Page 16: Stacks

Chapter 5: Stacks 16

Palindrome Finder

• Suppose string is “frank”• First, push letters onto stack…

f

frank

rf

frank

rf

a

frank

rf

an

frank

rf

ank

frank

Page 17: Stacks

Chapter 5: Stacks 17

Palindrome Finder

• Then pop letters off of stack and append to new string…

rf

an

kn

rf

knar

rf

a

kna

f

knarf

rf

ank

k

• Finally, compare original and new string:• We have frank != knarf, so not a palindrome

Page 18: Stacks

Chapter 5: Stacks 18

Class PalindromeFinder

Page 19: Stacks

Chapter 5: Stacks 19

Testing PalindromeFinder

• What types of strings should be test???• Single character (which is always a palindrome)• Single words

• Both palindromes and non-palindromes• Multiple words

• Both palindromes and non-palindromes• Different cases (upper/lower)• Even-length strings• Odd-length strings• Empty string (considered palindrome by default)

Page 20: Stacks

Chapter 5: Stacks 20

Balanced Parenthesis

• It is important to determine whether an expression is “balanced” with respect to parentheses

• For example• (a+b*(c/(d-e)))+(d/e) is balanced

• But• (a+b*(c/d-e)))+(d/e) is not balanced

• Problem is more complicated if braces or brackets (square and/or curly) are also used

• Good solution is to use stacks!• Here, we only consider parenthesis

Page 21: Stacks

Chapter 5: Stacks 21

ParenChecker Class

• Input: String (representing an expression)• Output: A message indicating whether expression is

balanced with respect to parenthesis or not• Of course, we want to use a stack…• What is the idea behind the algorithm?• Push open parenthesis onto stack• When closed parenthesis is encountered

• Try to pop top element off of stack• If no top element (stack is empty), not balanced

• When done, if stack is not empty, then not balanced

Page 22: Stacks

Chapter 5: Stacks 22

ParenChecker Algorithm

• Given expression to test…• Create an empty stack of characters• Set balanced = true (i.e., assume it is balanced)• Set index = 0• While balanced is true and index < expression length

• Get the next character in expression• If character in open parenthesis

• Push open parenthesis onto stack

• Else if character is closing parenthesis• If stack is empty, set balanced to false• Else pop element from stack

• Increment index• Return true if balanced is true and stack is empty

Page 23: Stacks

Chapter 5: Stacks 23

ParenChecker Class

Page 24: Stacks

Chapter 5: Stacks 24

ParenChecker Testing

• What data to test on?• Simple valid expressions (one level of matched parens)• Simple invalid expressions• More complex expressions (valid and invalid)

• Test too many open parens and too many closed parens

• Know the correct answer before testing an expression

Page 25: Stacks

Chapter 5: Stacks 25

Implementing a Stack

• In Java, Stack class extends Vector• Could also have been implemented using other Lists

• Such as ArrayList or LinkedList• Could also be implemented using Array• We’ll look (briefly) at each of these

Page 26: Stacks

Chapter 5: Stacks 26

Stack as a Vector

• The Java API includes a Stack class as part of the package java.util• The Vector class implements a growable array

• Elements of a vector accessed using an integer index• Size can grow or shrink as needed to accommodate

the adding and removing of elements• In following examples, push letters of “Java” onto stack:

Java

Page 27: Stacks

Chapter 5: Stacks 27

Stack as a Vector

Page 28: Stacks

Chapter 5: Stacks 28

Stack as a Vector

• Java Stack is an extension of Vector• Therefore, can use all Vector methods on a Stack• Is this a good thing?• You can access any element of a Vector

• So, you can access any element of a Stack• If you try to access elements of a Stack, you might get

ArrayIndexOutOfBoundsException• Best to restrict yourself to stack-specific methods

Page 29: Stacks

Chapter 5: Stacks 29

Stack as a List

• Can use ArrayList, Vector, LinkedList classes• Since all implement the List interface

• Name of class illustrated in text is ListStack<E>• Note that ListStack is an adapter class

• Gives different names to essentially same operations• Also true of Java’s Vector-based implementation

• For example, java.util.Stack<E> push is code ispublic E push(E obj) {

add(obj);return obj;

}

Page 30: Stacks

Chapter 5: Stacks 30

ListStack.java

public class ListStack < E > implements StackInt < E > {private List < E > theData;public ListStack() {

theData = new ArrayList < E > ();} public E push(E obj) {

theData.add(obj);return obj;

}. . .

Page 31: Stacks

Chapter 5: Stacks 31

Stack as an Array

• Allocate storage for an array with an initial default capacity when creating a new stack object

• Keep track of the top of the stack, topOfStack• For empty stack, topOfStack is set to -1

• No size method• Array size does not grow/shrink after each push/pop• However, must reallocate if more space needed

• This is very primitive• And that’s why I like it best…

Page 32: Stacks

Chapter 5: Stacks 32

Stack as an Array

Page 33: Stacks

Chapter 5: Stacks 33

Stack as an Arraypublic class ArrayStack < E > implements StackInt < E > {

E[] theData;int topOfStack = -1;private static final int INITIAL_CAPACITY = 10; public ArrayStack() {

theData = (E[])new Object[INITIAL_CAPACITY];}public E push(E obj) {

if (topOfStack == theData.length - 1) {reallocate();

}topOfStack++;theData[topOfStack] = obj;return obj;

}. . .

Page 34: Stacks

Chapter 5: Stacks 34

Stack as a Linked List

• Can implement a stack using a linked list of nodes• See code and details in text

Page 35: Stacks

Chapter 5: Stacks 35

Comparison of Stack Implementations

• Extending a Vector (as is done by Java) is a poor choice• All Vector methods are accessible• Then why does Java do it this way?

• What about ArrayList implementation?• Easiest to implement, ArrayList does all of the work…

• What about Array implementation?• Slightly more difficult for programmer

• What about Linked List implementation? • Uses only as much storage as needed• However, links are essentially wasted

• Regardless of method used, push/pop is O(1)

Page 36: Stacks

Chapter 5: Stacks 36

Stack Application

• We consider problem of evaluating math expressions• Postfix and infix notation• Expressions normally written in infix form

• Operators (+,-,*,/, etc.) between the operands• Good for humans, not so good for computers

• Computers prefer postfix notation• Operands come first, then operators

Page 37: Stacks

Chapter 5: Stacks 37

Postfix vs Infix

Page 38: Stacks

Chapter 5: Stacks 38

Postfix Advantages

• Advantage of postfix form include• No need for parentheses• No need to consider operator precedence

Page 39: Stacks

Chapter 5: Stacks 39

Evaluating Postfix Expressions

• Problem: Write a class to evaluate postfix expressions.• Analysis: Stack is good data structure to store operands

until needed• Design: Class PostfixEvaluator with methods

• Method eval: scans postfix expression and processes its tokens

• Method evalOp: evaluates each operator• Method isOperator: determine whether a character

is an operator

Page 40: Stacks

Chapter 5: Stacks 40

Evaluating Postfix Expressions

Page 41: Stacks

Chapter 5: Stacks 41

Evaluating Postfix Expressions

Page 42: Stacks

Chapter 5: Stacks 42

Evaluating Postfix Expressions

Page 43: Stacks

Chapter 5: Stacks 43

Converting Infix to Postfix

Page 44: Stacks

Chapter 5: Stacks 44

Converting Infix to Postfix

Page 45: Stacks

Chapter 5: Stacks 45

Converting Infix to Postfix

Page 46: Stacks

Chapter 5: Stacks 46

Converting Infix to Postfix

Page 47: Stacks

Chapter 5: Stacks 47

Converting Infix to Postfix

Page 48: Stacks

Chapter 5: Stacks 48

Chapter Review

• A stack is a last-in, first-out (LIFO) data structure• A stack is a simple but powerful data structure

• Four operations are empty, peek, pop, and push• Stacks are useful to process information in the reverse of

the order that it is encountered• In Java, Stack is implemented as an extension of the

Vector class

Page 49: Stacks

Chapter 5: Stacks 49

Chapter Review

• We considered 3 different ways to implement a stack: • Using the List interface as a container• Using an array as a container• Using a linked list as a container

• We applied stacks to evaluate arithmetic expressions