Chapter 6: Stacks - PowerPoint PPT Presentation

1 / 24
About This Presentation
Title:

Chapter 6: Stacks

Description:

Peek copying and returning the top item off the top of stack without removing it (optional) ... peek simply returns the data at the top node. clone is the ... – PowerPoint PPT presentation

Number of Views:21
Avg rating:3.0/5.0
Slides: 25
Provided by: NKU
Category:
Tags: chapter | peek | stacks

less

Transcript and Presenter's Notes

Title: Chapter 6: Stacks


1
Chapter 6 Stacks
  • The first of the new ADTs we will cover in class
  • A stack is much like a stack in the real world
  • items are placed one on top of each other and you
    always access the stack at the top rather than
    the middle or bottom
  • Consider a stack of trays in the cafeteria
  • You will push your tray on top of the rest, so
    the last tray added, is always on top
  • You will remove a tray from the top (removing is
    called a pop)
  • Stacks represent a list structure where access is
    only at one end, the top, and the accesses form a
    pattern called Last-in-first-out (LIFO)
  • or First-in-last-out
  • We will use a stack when we want to ensure that
    accesses to the list are done in a LIFO order
  • This will be useful for performing backtracking
    and parsing as we will see in this and later
    chapters

2
Stack Example
Empty Push 5 Push 8
  • Consider a stack of integers
  • Start with an empty stack
  • Push 5
  • Push 8
  • Push 13
  • Pop gives us 13 with 8 and 5 still on the stack
  • Push 12
  • Push 6
  • Pop gives us 6, with 12, 8 and 5 still on the
    stack
  • Popping the rest gives us, in order, 12, 8 and 5

8 5
5
Push 13 Pop Push 12
13
13 8 5
12 8 5
8 5
3
The Stack ADT
  • Methods
  • Constructor constructs an empty stack
  • Pushing a new item onto the stack
  • Popping the top item off of the stack and
    returning it
  • Empty determining if the stack is empty or not
  • Full determining if the stack has reached its
    capacity (optional)
  • Peek copying and returning the top item off the
    top of stack without removing it (optional)
  • Size returning the number of items currently
    pushed on the stack (optional)
  • Clone (optional)
  • Data structure
  • A collection that stores items of some type
  • Something that tells us where the top of the
    stack is
  • The capacity of the stack (optional)
  • The size of the stack (optional)
  • Implementation
  • Array
  • Linked List

4
An Array Based Stack of ints
public class IntStack int stack
int top public IntStack(int size)
top -1 stack new
intsize public boolean isEmpty(
) return (top -1)
public boolean isFull( )
return (top stack.length 1)
0 1 2 3 4
Stack of 5 elements goes from 0-4 Full if
top 4 Empty if top -1
top
The stack is an array of ints We start filling
from location 0 and push by adding to top So,
unlike the previous figure, we add to the stack
in a downward fashion Stack is empty if top is
not pointing to the array Stack is full if top
last element (length-1)
5
Stack Implementation continued
public void push(int x) if(!isFull( ))
top stacktop
x else System.out.println(Stack
full!) public int size(int x)
return top1
push(5) not full, so add one to top and add 5
there
5
Here, size returns the number of elements
pushed onto the stack We could also have size
return the top-of-stack index value (top)
6
Stack Implementation continued
public int pop( ) if(!isEmpty( ))
int temp stacktop
top-- return temp else
System.out.println(stack empty)
return 999 public int
peek( ) if(!isEmpty( ))
return stacktop else return 999

If stack is not empty, return item at top,
and decrement top
Return 5
Use 999 as an error value to indicate that the
stack is empty
Peek is similar to pop except that it doesnt
alter the top of stack
7
Stack Implementation continued
public IntStack clone( ) IntStack
copy try copy (IntStack)
super.clone( )
catch(CloneNotSupportedExecption o)
throw new RuntimeException
(Clone not supported)
copy.stack (int ) copy.clone( )
return copy
The clone method works by creating a copy of
all data instances of the IntStack object If
clone is not supported, an exception is thrown
Otherwise, the cloned object is casted as a
stack, and the array portion of the stack is
cloned, then the cloned stack is returned
8
Linked List Stack
  • The Linked List version of the Stack is similar
    in many ways to the Unordered Linked List and
    will use the IntNode class defined (see chapter 4
    notes)
  • We have a head pointer called top
  • Constructing the Stack simply sets top to null
  • If we want to push a new item
  • we add at the top (like inserting at the head)
  • If we want to remove
  • we only allow for the removal of the top item
    (like removing from the head)
  • isEmpty is true if top null
  • isFull is never true
  • we assume that we will never run out of memory
  • peek simply returns the data at the top node
  • clone is the same as listCopy

9
Stack Implementation
import IntNode public class LinkedStack
IntNode top public LinkedStack( )
top null
public boolean isEmpty( )
return (top null)
public boolean isFull( )
return false
public int peek( ) if(!isEmpty( ) )
return top.getData( )
else return 999
Empty Stack
top
Non-empty Stack
top
6 13 8 9
10
Stack Implementation continued
public void push(int x) if (!isFull(
)) IntNode temp new
IntNode(x, top) top temp
else System.out.println(Stack Full!)
public int pop( ) if(!isEmpty( ))
int temp top.getData( )
top top.getLink( )
return temp else return 999
Push 3 create a new IntNode
with data 3 and link top
reset top to point at the new IntNode
3
Pop return top.getData( ) reset
top to point at top.getLink( )
return this value
11
Array vs. Linked Implementations
  • Recall that there were good reasons to use arrays
    for a Bag ADT
  • binary search and random access
  • and good reasons to use a Linked List
  • no need to shift elements, no need to change
    capacity when adding new elements
  • This distinction is mostly untrue with Stacks
  • adding at one end only means no need to shift
    elements
  • no need for random access or binary search since
    we only access the top element
  • So, the only difference is because of needing to
    change the arrays capacity
  • a fairly minor problem, but we might favor the
    linked version because of it

12
Stack Complexities
13
Stack Applications
  • Reversing a word or words
  • Balancing parentheses
  • Evaluating fully parenthesized expressions
  • Translating infix to postfix notation
  • Evaluating postfix notation
  • Evaluating infix notation using precedence rules
  • - we will cover these topics, the others are in
    the textbook and you should look them over
    yourself

14
Printing a File Backwards
  • Consider a Stack ADT called StringStack

StringStack ss new StringStack( )
BufferedReader infile String input
infile.readLine( ) while(infile ! null)
ss.push(input) input
infile.readLine( ) String next
while(!ss.isEmpty( ) ) next ss.pop(
) System.out.println(next)
Stack The big bad wolf ate
File The big bad wolf ate the little
lamb.
top
infile
15
Parenthesis Matching
  • A common requirement of a compiler is the ability
    to match up parentheses
  • Consider the following expression
  • a(x 5) y (b4 b5)
  • y
  • We must make sure that the left and right hand
    symbols match up
  • We can parse through the expression, pushing each
    left item on a stack
  • If we reach a right item, we pop the top of the
    stack and compare, if they are the same type, it
    is legal, if wrong type then illegal

boolean failed false CharStack cs new
CharStack( ) for(int i0 ilts.length()
!failed i) if(s.charAt(i) (
s.charAt(i)
s.charAt(i) )
cs.push(s.charAt(i)) else if(s.charAt(i)
)) if(cs.pop( ) ! )) failed
true else if(s.charAt(i) )
if(cs.pop( ) ! ) failed true
else if(s.charAt(i) )
if(cs.pop( ) ! ) failed true return
failed
16
Evaluating an Expression
  • Consider that we want to evaluate a fully
    parenthesized expression like
  • ( (3 (6 (5 1) ) ) (6 / (2 1) ) )
  • If we evaluate in a strictly left-to-right
    manner, ignoring parentheses and operator
    precedence, we get the wrong answer
  • 3 6 9 5 45 1 44 6 50 / 2 25 1
    26
  • We must instead evaluate this left-to-right but
    not applying an operator until its correct
    precendence
  • parens first, and / next, and last
  • How?
  • Use two stacks, an operator stack and an operand
    stack
  • Push each operand in order onto the operand stack
  • Push each operator in order onto the operator
    stack
  • If a ) is found, pop the top two operands off the
    operand stack, pop the top operator off the
    operator stack, apply the operator (in opposite
    order) to the operands and push the result back
    on the operand stack
  • By the end of the expression, the result is on
    the top of the operand stack

17
Evaluating Our Example
  • Push / onto stack 2 (now /, )
  • Push 2 onto stack 1 (now 2, 6, 27)
  • Push onto stack 2 (now , /, )
  • Push 1 onto stack 1 (now 1, 2, 6, 27)
  • Right ), pop and apply to 1, 2 pushing 2 1
    onto stack 1 (now 3, 6, 27)
  • Right ), pop / and apply to 3, 6 pushing 6 / 3
    onto stack 1 (now 2, 27)
  • Right ), pop (stack 1 now empty) and apply to
    2, 27, pushing 27 2 onto stack 1
  • End of expression, result on top of stack (29)
  • ( (3 (6 (5 1) ) ) (6 / (2 1) ) )
  • Push 3 onto stack 1
  • Push onto stack 2
  • Push 6 onto stack 1 (now 6, 3)
  • Push onto stack 2 (now , )
  • Push 5 onto stack 1 (now 5, 6, 3)
  • Push onto stack 2 (now -, , )
  • Push 1 onto stack 1 (now 1, 5, 6, 3)
  • Right ), pop and apply to 1, 5 pushing 5 1
    onto operand 1 (now 4, 6, 3)
  • Right ), pop and apply to 4, 6 pushing 6 4
    onto stack 1 (now 24, 3)
  • Right ), pop (stack 1 now empty) and apply to
    24, 3, pushing 3 24 onto operand stack (now 27)
  • Push onto stack 2 (now )
  • Push 6 onto stack 1 (now 6, 27)

18
Expression Evaluation Code
public int readEvaluate(String expr)
IntStack s1 new IntStack( ) CharStack s2
new CharStack( ) char temp
for(int i0iltexpr.length 1 i)
temp expr.charAt(i)
if(Character.isDigit(temp))
s1.push(Integer.parseInt(temp)) else
if(temp temp -
temp temp /)
s2.push(temp) else if(temp
)) evaluateTop(s1, s2) int
answer s1.pop( ) if(s1.isEmpty( )
s2.isEmpty( )) return answer else return 999

public void evaluateTop(IntStack s1,
CharStack s2) int x2
s1.pop( ) int x1 s1.pop( ) char
op s2.pop( ) switch(op)
case s1.push(x1 x2) break
case - s1.push(x1 x2) break
case s1.push(x1 x2) break
case / if(s2!0) s1.push(x1 / x2) else
throw new IllegalArgumentException (division
by zero) break default throw
new IllegalArgumentException (Illegal
Operation)
19
Pre- and Post-fix Notations
  • We commonly view mathematical expression in infix
    notation
  • operator to be applied is placed in-between the
    two operands
  • example 5 12
  • In pre-fix notation, the operator precedes the
    operands and in post-fix notation, the operate
    succeeds the operands
  • 5 12
  • 5 12
  • There are two reasons why these notations are
    important
  • First, some calculators are based on post-fix
    notation, it allows the calculator to perform
    calculations without needing a memory
  • Second, expressions written in either of these
    notations need no parentheses to come out with
    the correct values

20
Examples
  • Convert the following in-fix notation into both
    pre- and post-fix notations
  • A (B (C / D E F) ) / (G H I)
  • Prefix / A B - / C D E F G H I
  • This can be evaluated as the division of (the
    multiplication of A and (the sum of B and (the
    difference of (the division of C and D) and (the
    multiplication of E and F) and the sum of (G and
    the multiplication of H and I))))
  • Postfix A B C D / E F - G H I /

21
Using a Stack to Create Postfix
  • We will skip creating the pre-fix expression
  • But here is a simple algorithm to take a fully
    parenthesized infix expression and create the
    postfix expression from it
  • Initialize a CharStack
  • Do
  • Read the next symbol
  • if (symbol () push (onto stack
  • else if (symbol is an operand) write the operand
    to output
  • else if (symbol is an operator) push symbol onto
    stack
  • else if (symbol )) then continue to pop
    items off of the stack and output them until a
    ) is reached (do not output the ))
  • While (there is more expression to read)
  • Pop and output the remainder of the stack
    (excluding ))

22
Example
Output Stack top ? ( ( ( 2
( ( ( ( ( ( (
( ( ( ( ( ( 2 A ( ( ( ( ( - 2 A B
2 A B - ( ( ( ( 2 A B - ( ( ( 2 A B
( ( ( 2 A B 3 ( ( ( 2 A B 3 ( (
( 2 A B 3 C ( ( ( 2 A B - 3 C
  • Expression is ( ( (2 (A B) ) 3) C)
  • Read (, push onto stack (3 times)
  • Read 2, output it
  • Read (, push onto stack
  • Read , push onto stack
  • Read (, push onto stack
  • Read A, output it
  • Read -, push onto stack
  • Read B, push onto stack
  • Read ), discard it, pop off stack until ( and
    output each item except (
  • Read ), discard it, pop off stack until (
  • Read , push onto stack
  • Read 3, output it
  • Read , push onto stack
  • Read C, output it
  • Input empty, pop all remaining items off of stack
    outputting them (other than ))
  • Answer is 2 A B - 3 C

23
Evaluating a Postfix Expression
  • Somewhat similar to evaluating a fully
    parenthesized infix expression
  • Have an operand stack
  • Parse the input doing the following for each
    input item
  • If item is an operand, push it onto the stack
  • If item is an operator
  • pop the first two items off the stack
  • apply the operator in the order (second item)
    operator (first item)
  • push the resulting value back onto the stack
  • Once the input is complete, pop off the top item
    of the stack, it is the evaluated expression (and
    should be the only thing on the stack)

24
Example
  • Lets evaluate our previous postfix expression
    using the following values
  • A B C D / E F - G H I /
  • A 10 B 2 C 40 D 2 E 2 F 9 G
    4 H 2 I 3
  • Push 10, Push 2, Push 40, Push 2
  • Reach /, pop 2 and 40, apply 40 / 2 and Push
    result (20)
  • Push 2, Push 9
  • Reach , pop 9 and 2, apply 9 2, and Push
    result (18)
  • Reach -, pop 18 and 20, apply 20 18, and Push
    result (2)
  • Reach , pop 2, pop 2, apply 2 2, and Push
    result (4)
  • Reach , pop 4, pop 10, apply 10 4, and Push
    result (40)
  • Push 4, Push 2, Push 3
  • Reach , pop 3, pop 2, apply 2 3, and Push
    result (6)
  • Reach , pop 6, pop 4, apply 4 6, and Push
    result (10)
  • Reach / , pop 10, pop 40, apply 40 / 10, and Push
    result (4)
  • End of input, pop result, 4 is the answer
  • Check to make sure
  • A (B (C / D E F) ) / (G H I) 4 for
    the above values
Write a Comment
User Comments (0)
About PowerShow.com