Title: Chapter 6 Stacks
1Chapter 6Stacks
- CS 260 Data Structures
- Indiana University Purdue University Fort Wayne
2The stack ADT
- A stack is one of the most useful of all data
structures - A stack is a sequence of elements in which
elements can be added or removed only at one end
called the top - Behavior
- push
- pop
- peek
- isEmpty
- size
3The stack ADT
- A stack has LIFO behavior
- Underflow
- An attempt to pop or peek an empty stack
- Typical implementations
- Element type is . . .
- a generic object ltEgt
- one of the primitive types
- Store elements in an array
- Store elements in a linked list
- We will look at some applications before
considering implementation
4Arithmetic expression evaluation
- Consider the arithmetic expression
- ( ( ( 7 2 ) ( ( 3 5 ) ( 2 6 ) ) ) (
( 19 5 ) / 2 ) ) - This expression is fully-parenthesized to avoid
considering operator precedence for now - Evaluation uses two stacks
- Number stack of operands
- Operation stack of operators
- It is best if the expression can be processed in
a left-to-right order without backtracking
5Rules for arithmetic expression evaluation
- When the next token is an . . .
- operand (i.e., a number)
- Push the operand onto the number stack
- operator
- Push the operator on the operator stack
- right parenthesis
- Perform an evaluation step
- Pop the top two values from the number stack
- Pop the top operator from the operator stack
- Combine the numbers using the operator
- Second number popped is the left operand
- Push the result on the number stack
- left parentheses or a blank
- Throw it away
- We wont be concerned with checking for balanced
parentheses at this time
6Example
- ( ( ( ( 7 2 ) ( ( 3 5 ) ( 2 6 ) ) ) (
19 5 ) ) / 2 ) - Notation for displaying stack manipulation
- Pushed elements go on top of a column
- Whenever a pop occurs, copy the remaining
elements into the next column with a bar
indicating the top - The horizontal bar indicates how many elements
were popped
number stack
operation stack
7Arithmetic expression evaluation
public static void evaluateStackTops(
StackltDoublegt numbers, StackltCharactergt
operations ) double operand1, operand2
// Check that the stacks have enough items, and
get the two operands. if ( ( numbers.size( )
lt 2 ) ( operations.isEmpty( ) ) )
throw new IllegalArgumentException( "Illegal
expression ) operand2
numbers.pop( ) operand1 numbers.pop( )
// Carry out an action based on the operation
on the top of the stack. switch (
operations.pop( ) ) case ''
numbers.push( operand1 operand2 ) break
case '-' numbers.push( operand1 - operand2 )
break case '' numbers.push( operand1
operand2 ) break case '/' // Here,
division by zero is possible resulting in one of
the constants //
Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINI
TY numbers.push( operand1 /
operand2 ) break default throw new
IllegalArgumentException( "Illegal operation )
8public static double evaluate( String expression
) StackltDoublegt numbers new
StackltDoublegt( ) StackltCharactergt
operations new StackltCharactergt( )
Scanner input new
Scanner( expression ) String
next while ( input.hasNext( ) )
if ( input.hasNext( UNSIGNED_DOUBLE )
next input.findInLine(
UNSIGNED_DOUBLE )
numbers.push( new Double( next ) )
else next input.findInLine(
CHARACTER ) switch(
next.charAt( 0 ) ) case
case -
case case
/ operations.push( next.charAt( 0 ) break
case )
evaluateStackTops( numbers, operations ) break
case ( break
default throw new
IllegalArgumentException( Illegal character )
if ( numbers.size( ) !
1 ) throw new IllegalArgumentException(
"Illegal input expression ) return
numbers.pop( )
9Arithmetic expression evaluation
- The Scanner class and the Pattern class used for
input are described in Appendix B, pp. 750 754 - UNSIGNED_DOUBLE is a Pattern
- Method evaluate is a O( n ) method
- Possible improvements
- Detect all illegal arithmetic expressions
- Permit expressions that are not fully
parenthesized - The evaluation technique then must deal with
precedence rules - We will consider this situation later
10Another example
- Consider expressions consisting only of
parentheses and check that the parentheses are
balanced - For more interest, consider ( ), , and
- Balanced ( ( ) )
- Not balanced ( )
- It is not sufficient to just count each type of
parenthesis and compare the numbers of left
parentheses with the corresponding right
parentheses
11Balance checking technique
- Technique
- Work left to right
- Use a stack of parentheses
- Push any left parenthesis
- For a right parenthesis, pop the stack and
compare - The expression is not balanced if . . .
- Stack underflow occurs on pop
- No more input exists but the stack is not empty
- A left parenthesis does not match the right
parenthesis
12Balance checking method
public static boolean isBalanced( String
expression ) final char LEFT_NORMAL
'(' final char RIGHT_NORMAL ')'
final char LEFT_CURLY '' final
char RIGHT_CURLY '' final char
LEFT_SQUARE '' final char
RIGHT_SQUARE '' // Instantiate a
stack to store left parentheses
StackltCharactergt store new StackltCharactergt(
) int i
// An index into the string boolean
failed false // Change to true for a
mismatch ? ? ?(continued on next slide)
13 ? ? ? for (i 0 ! failed ( i lt
expression.length( ) ) i )
switch ( expression.charAt( i ) )
case LEFT_NORMAL case
LEFT_CURLY case LEFT_SQUARE
store.push(
expression.charAt( i ) )
break case RIGHT_NORMAL
if ( store.isEmpty( ) (
store.pop( ) ! LEFT_NORMAL ) )
failed true
break case RIGHT_CURLY
if ( store.isEmpty( ) (
store.pop( ) ! LEFT_CURLY ) )
failed true
break case RIGHT_SQUARE
if ( store.isEmpty( ) (
store.pop( ) ! LEFT_SQUARE ) )
failed true
break return
( store.isEmpty( ) ! failed )
14Stack implementation using an array
- Generic class ArrayStackltEgt
- State
- private E data
- private int manyItems // internal name
for top - Implementations of methods push and pop are on
the next slide - EmptyStackException used there is from java.util.
- ADT invariant of the ArrayStack class
- The number of items in the stack is stored in the
instance variable manyItems - The items in the array are stored in a
partially-filled array called data, with the - bottom of the stack at data 0 , the next item
at data 1 , and so on to the top - of the stack at data manyItems 1
15Stack implementation using an array
public void push( E item ) if ( manyItems
data.length ) ensureCapacity(
manyItems2 1 ) data manyItems
item manyItems
6 5 4 3 2 1 0
public E pop( ) E answer if (
manyItems 0 ) throw new
EmptyStackException( ) manyItems--
answer data manyItems data manyItems
null return answer
manyItems
16Stack implementation using a linked list
- Generic class LinkedStackltEgt
- State
- private NodeltEgt top
- ADT invariant of the LinkedStack class
- The items in the stack are stored in a linked
list, with the top of the stack - stored at the head node, down to the bottom of
the stack at the final node - The instance variable top is the head reference
of the linked list of items
17Stack implementation using a linked list
public void push( E item ) top new
NodeltEgt( item, top )
public E pop( ) E answer if ( top
null ) throw new
EmptyStackException( ) answer
top.getData( ) top top.getLink( )
return answer
33
11
19
92
56
top
18Postfix (Polish) arithmetic expressions
- In postfix (or Polish) notation, the operator
comes after the operands - No parentheses are needed
- HP pocket calculators use postfisx notation
- Example
infix notation ( 72 35 26 )( 19 5 )
/ 2 postfix notation 7 2 3 5
2 6 19 5 - 2 /
19Evaluation of postfix expressions
- Evaluation uses just one stack
- Number stack of operands
- Example
- 7 2 3 5 2 6 19 5 -
2 /
number stack
20Arithmetic expression evaluation
- Our goal is to evaluate arithmetic expressions
that are not fully-parenthesized - If we could translate a normal infix expression
(one that is not fully parenthesized) to postfix,
then we have seen that evaluation is easy - We now develop an algorithm to do this
translation - Of course, this algorithm must take account of
operator precedence among , -, , and /
21Translating infix to postfix
- Use a single stack of tokens
- Work left to right
- Push any ( on the stack
- Write any operand to output
- When any operator is read
- Pop and output operators from the stack until one
of the following occurs - the stack is empty
- top (
- top is an operator of lower precedence than the
operator that was read - Then push the operator that was read
- When a ) is encountered . . .
- Pop and output operations until top (
- Then pop the ( and discard
- When there in no more input
- Pop and output remaining operators from the stack
22Translating infix to postfix
- Example ( 72 35 26 )( 19 5 ) / 2
operand stack
output 7 2 3 5 2 6 19 5
- 2 /