Title: Stacks
1Stacks
- The unorganized persons data structure
2Stack characteristics
- Entries are ordered in terms of access -- both
insertion and removal take place at same spot
(top of stack) - Specialized type of container class defining
characteristic is insertion/removal order - LIFO last in, first out entries are removed in
reverse order of insertion
3Stack operations
- Push -- insert item on stack
- Pop -- remove item from stack
- Peek -- examine, but dont remove item
4Stack operations
- Important to know if stack is empty -- attempt to
remove an item from an empty stack is an
underflow error - Depending on implementation, may be necessary to
check if stack is full -- attempt to add item to
a full stack is an overflow error
5Implementation of Stack ADT
- Stacks can be array based (static or dynamic) or
linked list based - Invariant for static array implementation
- The number of items stored in the stack is found
in member variable used - Items are stored in member variable data, a
static array with the stack bottom at data0 and
the stack top at dataused - 1
6Stack class -- static array version
- template ltclass Itemgt
- class Stack
-
- public
- enum CAPACITY 64
- Stack ( ) // default constructor
- Item pop ( ) // removes top Item
- Item peek ( ) const // reveals top Item
- . . .
7Stack ADT continued
- void push (const Item entry) // adds Item to
stack - size_t size ( ) const return used
- bool is_empty ( ) const return used 0
- private
- Item dataCAPACITY // the stack itself
- size_t used // of items stored in stack
-
8Stack function implementations constructor
- // Postcondition empty stack is created
- template ltclass Itemgt
- StackltItemgtStack( )
-
- used 0
-
9Pop function
- // Precondition stack is not empty
- // Postcondition top item is removed
- template ltclass Itemgt
- Item StackltItemgtpop ( )
-
- assert (!is_empty( ))
- used--
- return dataused
10Peek function
- // Precondition stack is not empty
- // Postcondition top item is revealed
- template ltclass Itemgt
- Item StackltItemgtpeek ( ) const
-
- assert (!is_empty( ))
- return dataused - 1
-
11Push function
- // Precondition stack is not full
- // Postcondition an item is inserted on stack
- template ltclass Itemgt
- void StackltItemgtpush(const Item entry)
-
- assert (size() lt CAPACITY)
- dataused entry
- used
-
12Stack application examples
- Compilers use stacks for a variety of purposes
- syntax analysis matching brackets, parentheses,
etc. - activation records structures associated with
functions, keeping track of local variables,
return address, etc.
13Example application balanced parentheses
- Pseudocode algorithm
- scan string left to right
- if ( is encountered, push on stack
- if ) is encountered, and stack is not empty,
pop one ( -- if stack is empty, expression is
unbalanced - if stack is empty when entire string has been
scanned and analyzed, expression is balanced
14A program to test for balanced parentheses
int main( ) String user_input // uses String
data type defined in ch. 4 - based on array
cout ltlt "Type a string with some parentheses and
no white space\n" cin gtgt user_input
if (balanced_parentheses(user_input))
cout ltlt "Those parentheses are balanced.\n"
else cout ltlt "Those parentheses are not
balanced.\n" cout ltlt "That ends this
balancing act.\n" return EXIT_SUCCESS
15balanced_parentheses function
bool balanced_parentheses(const String
expression) // Library facilities used assert.h,
stack1.h, stdlib.h, mystring.h. //
Meaningful names for constants const char
LEFT_PARENTHESIS '(' const char
RIGHT_PARENTHESIS ')' Stackltchargt
store // Stack to store the left parentheses as
they occur size_t i // An
index into the String char next
// The next character from the String char
discard // A char popped off the stack
and thrown away bool failed false //
Becomes true if a needed parenthesis is not
found . . .
16balanced_parentheses continued
for (i 0 !failed (i lt expression.length(
)) i) next expressioni
if (next LEFT_PARENTHESIS)
if (store.size( ) lt store.CAPACITY)
store.push(next) else if
((next RIGHT_PARENTHESIS) (!store.is_empty(
))) discard store.pop( )
else if ((next RIGHT_PARENTHESIS)
(store.is_empty( ))) failed true
return (store.is_empty( ) !failed)
17Stack ADT as linked list
- Can make use of toolkit functions to simplify
task - Stack can grow shrink as needed to accommodate
data -- no fixed size - Invariant
- stack items are stored in a linked list
- member variable top is head pointer to list
18Class definition for new Stack
- template ltclass Itemgt
- class Stack
-
- public
- Stack( ) top NULL
- Stack(const Stack source)
- Stack( ) list_clear(top)
- ...
19Stack definition continued
- void push(const Item entry)
- Item pop( )
- void operator (const Stack source)
- size_t size( ) const return list_length(top)
- bool is_empty( ) const return top NULL
- Item peek( ) const
- private
- NodeltItemgt top // Points to top of stack
-
20Push function
- template ltclass Itemgt
- void StackltItemgtpush(const Item entry)
-
- list_head_insert(top, entry)
21Pop function
- template ltclass Itemgt
- Item StackltItemgtpop( )
-
- assert(!is_empty( ))
- Item answer top-gtdata
- list_head_remove(top)
- return answer
22Peek function
- template ltclass Itemgt
- Item StackltItemgtpeek( ) const
-
- assert(!is_empty( ))
- return top-gtdata
23Copy constructor
- template ltclass Itemgt
- StackltItemgtStack(const StackltItemgt source)
-
- list_copy(source.top, top)
24Assignment operator
- template ltclass Itemgt
- void StackltItemgtoperator (const StackltItemgt
source) -
- if (source.top top) // Handle self-assignment
- return
- list_clear(top)
- list_copy(source.top, top)
-
25A stack-based calculator
- Input to program is a fully-parenthesized
expression -- examples - ((5.3 1.2) / 3.1)
- (4 - 3)
- Two stacks are used -- one for operators, one for
operands - Right parenthesis is signal to pop the stacks and
evaluate the expression
26Algorithm for expression evaluation
- Evaluate leftmost, innermost expression continue
evaluating, left to right - Read each part of expression
- Push numbers on operand stack, operators on
operator stack - When right parenthesis is encountered, pop the
stacks, evaluate, and push result on operand stack
27Code for stack calculator
- int main( )
-
- double answer
- cout ltlt "Type a fully parenthesized
arithmetic expression" ltlt endl - answer read_and_evaluate(cin)
- cout ltlt "That evaluates to " ltlt answer ltlt
endl - return EXIT_SUCCESS
28Code for stack calculator
- double read_and_evaluate(istream ins)
-
- const char DECIMAL '.'
- const char RIGHT_PARENTHESIS ')'
- Stackltdoublegt numbers
- Stackltchargt operations
- double number
- char symbol
- ...
29Code for stack calculator
- while (!ins.eof( ) ins.peek( ) ! '\n')
-
- if (isdigit(ins.peek( )) (ins.peek( )
DECIMAL)) -
- ins gtgt number
- numbers.push(number)
-
-
30Code for stack calculator
- else if (strchr("-/", ins.peek( )) ! NULL)
-
- ins gtgt symbol
- operations.push(symbol)
-
31Code for stack calculator
- else if (ins.peek( ) RIGHT_PARENTHESIS)
-
- cin.ignore( )
- evaluate_stack_tops(numbers,
operations) -
- else
- cin.ignore( )
- // end of while loop
- return numbers.pop( )
32Code for stack calculator
- void evaluate_stack_tops(Stackltdoublegt numbers,
Stackltchargt operations) -
- double operand1, operand2
- operand2 numbers.pop( )
- operand1 numbers.pop( )
- ...
33Code for stack calculator
- switch (operations.pop( ))
-
- case ''
- numbers.push(operand1 operand2)
- break
- case '-'
- numbers.push(operand1 - operand2)
- break
- ...
34Code for stack calculator
- case ''
- numbers.push(operand1 operand2)
- break
- case '/'
- numbers.push(operand1 / operand2)
- break
- // end switch statement
- // end function