Stacks Chapter 5 Stacks Chapter Objectives To learn
Stacks Chapter 5: Stacks
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 Chapter 5: Stacks 2
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 Chapter 5: Stacks 3
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. Chapter 5: Stacks 4
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 Chapter 5: Stacks 5
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) Chapter 5: Stacks 6
Specification of the Stack Abstract Data Type (continued) Chapter 5: Stacks 7
Stack. Int<E> Interface /** Stack is a LIFO data structure */ public interface Stack. Int < 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(); } Chapter 5: Stacks 8
Stack Example • Suppose we have a stack called names Trudy Bob Alice • And we execute names. pop(); • What is the return value? • “Trudy” and the stack is Bob Alice Chapter 5: Stacks 9
Stack Example • We now have the stack Bob Alice • And we execute names. push(“Charlie”); • What is the return value? • “Charlie” and stack is Charlie Bob Alice Chapter 5: Stacks 10
Stack Example • We now have the stack Charlie Bob Alice • And we execute names. peek(); • What is the return value? • “Charlie” and stack is Charlie Bob Alice Chapter 5: Stacks 11
Stack Example • We now have the stack Charlie Bob Alice • And we execute names. empty(); • What is return value? • Returns false and stack is Charlie Bob Alice Chapter 5: Stacks 12
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) Chapter 5: Stacks 13
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! Chapter 5: Stacks 14
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 Chapter 5: Stacks 15
Palindrome Finder • Suppose string is “frank” • First, push letters onto stack… frank f frank r f frank a r f frank n a r f Chapter 5: Stacks frank k n a r f 16
Palindrome Finder • Then pop letters off of stack and append to new string… k kn knar k n a r f knarf f • Finally, compare original and new string: • We have frank != knarf, so not a palindrome Chapter 5: Stacks 17
Class Palindrome. Finder Chapter 5: Stacks 18
Testing Palindrome. Finder • 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) Chapter 5: Stacks 19
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 Chapter 5: Stacks 20
Paren. Checker 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 Chapter 5: Stacks 21
Paren. Checker 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 Chapter 5: Stacks 22
Paren. Checker Class Chapter 5: Stacks 23
Paren. Checker 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 Chapter 5: Stacks 24
Implementing a Stack • In Java, Stack class extends Vector • Could also have been implemented using other Lists • Such as Array. List or Linked. List • Could also be implemented using Array • We’ll look (briefly) at each of these Chapter 5: Stacks 25
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: a v a J Chapter 5: Stacks 26
Stack as a Vector Chapter 5: Stacks 27
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 Array. Index. Out. Of. Bounds. Exception • Best to restrict yourself to stack-specific methods Chapter 5: Stacks 28
Stack as a List • Can use Array. List, Vector, Linked. List classes • Since all implement the List interface • Name of class illustrated in text is List. Stack<E> • Note that List. Stack 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 is public E push(E obj) { add(obj); return obj; } Chapter 5: Stacks 29
List. Stack. java public class List. Stack < E > implements Stack. Int < E > { private List < E > the. Data; public List. Stack() { the. Data = new Array. List < E > (); } public E push(E obj) { the. Data. add(obj); return obj; }. . . Chapter 5: Stacks 30
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, top. Of. Stack • For empty stack, top. Of. Stack 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… Chapter 5: Stacks 31
Stack as an Array Chapter 5: Stacks 32
Stack as an Array public class Array. Stack < E > implements Stack. Int < E > { E[] the. Data; int top. Of. Stack = -1; private static final int INITIAL_CAPACITY = 10; public Array. Stack() { the. Data = (E[])new Object[INITIAL_CAPACITY]; } public E push(E obj) { if (top. Of. Stack == the. Data. length - 1) { reallocate(); } top. Of. Stack++; the. Data[top. Of. Stack] = obj; return obj; }. . . Chapter 5: Stacks 33
Stack as a Linked List • Can implement a stack using a linked list of nodes • See code and details in text Chapter 5: Stacks 34
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 Array. List implementation? • Easiest to implement, Array. List 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) Chapter 5: Stacks 35
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 Chapter 5: Stacks 36
Postfix vs Infix Chapter 5: Stacks 37
Postfix Advantages • Advantage of postfix form include • No need for parentheses • No need to consider operator precedence Chapter 5: Stacks 38
Evaluating Postfix Expressions • Problem: Write a class to evaluate postfix expressions. • Analysis: Stack is good data structure to store operands until needed • Design: Class Postfix. Evaluator with methods • Method eval: scans postfix expression and processes its tokens • Method eval. Op: evaluates each operator • Method is. Operator: determine whether a character is an operator Chapter 5: Stacks 39
Evaluating Postfix Expressions Chapter 5: Stacks 40
Evaluating Postfix Expressions Chapter 5: Stacks 41
Evaluating Postfix Expressions Chapter 5: Stacks 42
Converting Infix to Postfix Chapter 5: Stacks 43
Converting Infix to Postfix Chapter 5: Stacks 44
Converting Infix to Postfix Chapter 5: Stacks 45
Converting Infix to Postfix Chapter 5: Stacks 46
Converting Infix to Postfix Chapter 5: Stacks 47
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 Chapter 5: Stacks 48
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 Chapter 5: Stacks 49
- Slides: 49