1. Stacks
Learning Objectives:
To introduce the stack data structure.
To be able to implement the most common operations
Stacks 1
on stacks.
Apply stacks to solve common problems
2. Stacks
Outlines
1. INTRODUCTION
2. STL
3. ERROR PROCESSING
4. SPECIFICATION FOR METHODS
5. CLASS STACK
6. REVERSING A LIST
7. REVERSING A WORD.
8. RPN CALCULATOR
9. BRACKET MATCHING
10. EVALUATING ARITHMETIC
Stacks 2
EXPRESSIONS
3. 1. INTRODUCTION
A stack is a data structure in which all
insertions and deletions of entries are made at
one end, called the top of the stack. The last
entry which is inserted is the first one that will
be removed.
Stacks 3
4. 1. INTRODUCTION
Push box Q onto empty stack
Push box A onto stack
Pop a box from stack
Pop a box from stack
Stacks 4
5. 2. STL
The standard template library (STL) in C++ contains much useful
information, many functions, and many classes.
The STL provides convenient implementations for many common data
structures, including almost all the data structures we shall study.
We can include the STL stack implementation into our programs with the
Stacks 5
directive:
#include <stack>
and then we can utilize initially empty stack objects and apply methods
called push, pop, top, and empty.
In C++, a template construction allows us to create data structures
whose entries have different types. Example:
stack<double> numbers
stack<int> numbers
6. 2. STL
The STL provides several implementations of
various data structures such as stacks.
The code in a client program should not
depend on a particular choice of
implementation, but the performance of the
final program may very much depend on the
choice of implementation.
A second, optional template parameter selects
Stacks 6
the implementation.
7. 3. ERROR PROCESSING
We must recognize that a method might be applied illegally by
a client, e.g. a client might try to pop an empty stack.
We shall use a single enumerated type called Error_ code to
report errors from all of our programs and functions.
The enumerated type Error code is part of the utility package
Stacks use three values of an Error code:
Stacks 7
success
overflow
underflow
8. 4. SPECIFICATION FOR METHODS
Stacks 8
Error_code Stack ::pop( );
Pre: None.
Post: If the Stack is not empty, the top of the
Stack is removed. If the Stack is empty, an Error
code of underflow is returned and the Stack is
left unchanged.
Error_code Stack ::push(const Stack_entry &item);
Pre: None.
Post: If the Stack is not full, item is added to the
top of the Stack. If the Stack is full, an Error
code of overflow is returned and the Stack is
left unchanged.
9. 4. SPECIFICATION FOR METHODS
Error_code Stack ::top(Stack_entry &item) const;
Pre: None.
Post: The top of a nonempty Stack is copied to
item. A code of fail is returned if the Stack is
empty.
Stacks 9
bool Stack ::empty( ) const;
Pre: None.
Post: A result of true is returned if the Stack is
empty, otherwise false is returned.
10. 5. Class Stack We set up an array to hold the entries in the stack and a counter to indicate how many entries
Stacks 10
there are.
typedef int Stack_entry;
const int maxstack = 10; //small value for testing
class Stack {
public:
Stack( );
bool empty( ) const;
Error code pop( );
Error code top(Stack_entry &item) const;
Error code push(const Stack_entry &item);
private:
int count;
Stack_entry entry[maxstack];
};
The declaration of private visibility for the data makes it is impossible for a client to access the
data stored in a Stack except by using the methods push( ), pop( ), and top( ).
Important result: A Stack can never contain illegal or corrupted data. In general, data is said to
be encapsulated if it can only be accessed by a controlled set of functions.
11. 5. CLASS STACK
Topic 8 Stacks 11
Empty stack
Push the first entry (item)
N items on the stack
12. 5. CLASS STACK
Error_code Stack ::push(const Stack_entry &item)
/* Pre: None.
Post: If the Stack is not full, item is added to the top of the Stack
. If the Stack is full, an Error_code of overflow is returned and
the Stack is left unchanged.*/
Stacks 12
{
Error_code outcome = success;
if (count >= maxstack)
outcome = overflow;
else
entry[count++] = item;
return outcome;
}
13. 5. CLASS STACK
Topic 8 Stacks 13
Error_code Stack ::pop( )
/* Pre: None.
Post: If the Stack is not empty, the top of the Stack is removed. If
the Stack is empty, an Error_code of underflow is returned. */
{
Error_code outcome = success;
if (count == 0)
outcome = underflow;
else
--count;
return outcome;
}
14. 5. CLASS STACK
Error_code Stack ::top(Stack_entry &item) const
/* Pre: None.
Post: If the Stack is not empty, the top of the Stack is returned in
item . If the Stack is empty an Error_code of underflow is
returned. */
Stacks 14
{
Error_code outcome = success;
if (count == 0)
outcome = underflow;
else
item = entry[count . 1];
return outcome;
}
15. 5. CLASS STACK
Stacks 15
bool Stack ::empty( ) const
/* Pre: None.
Post: If the Stack is empty, true is returned. Otherwise false is returned.
*/
{
bool outcome = true;
if (count > 0) outcome = false;
return outcome;
}
Stack ::Stack( )
/* Pre: None.
Post: The stack is initialized to be empty. */
{
count = 0;
}
16. 6. REVERSING A LIST
10
12
10
14
12
16
14
12
14
12
12
Stacks 16
#include <stack>
int main(){
int n; double item; stack<double> numbers;
cout<<“Type an integer n: ”
cin>>n;
cout<<“Enter “<< n <<“ numbers: n”
for(int i=0; i<n; i++){
cin>>item;
numbers.push(item);
}
cout<<endl<<endl;
while(!numbers.empty()){
cout<<numbers.top() << “ “;
numbers.pop();
}
cout<<endl<<endl;
}
Type an integer n: 4
Enter 4 numbers:
10
12
14
16
16 14 12 10
10
16
14
12
10
10
10
10
10
17. 7. REVERSING A WORD
Read in a word and then write it out backward.
NATTAN ESIOTROTTORTOISE.
Pseudocode
//reversing a word
While(there are more characters of the word to read)
Read a character, and push the char onto the stack
Write Top(T)
then pop
Stacks 17
While(the stack is not empty)
Write the top char to the screen, and pop it off the stack
Write Top(N)
then pop
N
A
N
T
A
N
Push N
Push A
Push T
A
N
Output:TAN
Write Top(A)
then pop
N
18. 8. RPN CALCULATOR
In a Reverse Polish Notation (RPN) calculator,
the operands (usually numbers) are entered before an operation (like addition,
subtraction, multiplication, or division) is specified
(a b +), (4 5 6 * +), …etc // a, b, 4, 5, 6 are operands, + and * are operators.
The operands are pushed onto a stack.
When an operation is performed, it pops its operands from the stack and pushes
30
Stacks 18
its result back onto the stack.
4 5 6 * +
4
4 5
4 5 6
5*6=30
4
4+30=34
4 34
34
1
2
3
4 5 6
7
8
19. 8. RPN CALCULATOR
typedef double Stack_entry;
#include "stack.h"
int main( )
/* Post: The program has executed simple arithmetic commands entered by
the user.
Uses: The class Stack and functions introduction, instructions ,do
command ,and get command. */
{
Stack stored_numbers;
introduction( );
instructions( );
while (do_command(get_command( ), stored_numbers));
Stacks 19
}
21. 8. RPN CALCULATOR
bool do command(char command, Stack &numbers)
/* Pre: The first parameter species a valid calculator command.
Post: The command specified by the first parameter has been applied to the Stack
of numbers given by the second parameter. A result of true is returned unless
command == ‘q’ . */
{ double p, q;
switch (command) {
case ‘?’: cout << " Enter a real number: " <<flush; cin >> p;
if (numbers.push(p) == overflow) cout << " Warning: Stack full, lost number" <<endl; break;
case ‘=‘: if (numbers.top(p) == underflow) cout << " Stack empty" <<endl;
Stacks 21
else cout << p << endl; break;
case ‘+’: if (numbers.top(p) == underflow) cout << " Stack empty" <<endl;
else {
numbers.pop( );
if (numbers.top(q) == underflow) {
cout << " Stack has just one entry" <<endl;
numbers.push(p); }
else { numbers.pop( );
if (numbers.push(q C p) == overflow)
cout << " Warning: Stack full, lost result" <<endl; }
} break;
// Add options for further user commands.
case ‘q’: cout << " Calculation finished.n"; return false;
} return true; }
22. 9. BRACKET MATCHING
We develop a program to check that brackets are correctly
matched in an input text file.
We limit our attention to the brackets {, }, ( , ), [, and ].
We read a single line of characters and ignore all input other
Stacks 22
than bracket characters.
Algorithm: Read the le character by character. Each opening
bracket ( , [, or{ that is encountered is considered as
unmatched and is stored until a matching bracket can be
found. Any closing bracket ), ], or} must correspond, in
bracket style, to the last unmatched opening bracket, which
should now be retrieved and removed from storage. Finally,
at the end of the program, we must check that no unmatched
opening brackets are left over.
23. 9. BRACKET MATCHING
A program to test the matching of brackets needs to process
its input le character by character, and, as it works its way
through the input, it needs some way to remember any
currently unmatched brackets.
These brackets must be retrieved in the exact reverse of their
input order, and therefore a Stack provides an attractive
option for their storage.
Our program need only loop over the input characters, until
either a bracketing error is detected or the input le
ends.Whenever a bracket is found, an appropriate Stack
operation is applied.
Stacks 23
24. 9. BRACKET MATCHING
int main( )
/* Post: The program has notied the user of any bracket mismatch in the standard input file. Uses: The class Stack . */
{ Stack openings; char symbol; bool is matched = true;
Stacks 24
while (is matched && (symbol = cin.get( )) != 0n0) {
if (symbol == ‘{‘ || symbol == ‘(‘ || symbol == ‘[‘)
openings.push(symbol);
if (symbol == ‘}’ || symbol == ‘)’ || symbol == ‘]’) {
if (openings.empty( )) {
cout << " Unmatched closing bracket " <<symbol
<< " detected." <<endl;
Is_matched = false;
}
else {
char match;
openings.top(match);
openings.pop( );
is matched = (symbol == ‘}’ && match == ‘{‘) || (symbol == ‘)’ && match == ‘(‘) || (symbol == ‘]’ && match == ‘[‘);
if (!is matched)
cout << " Bad match " <<match << symbol << endl;
}
}
}
if (!openings.empty( ))
cout << " Unmatched opening bracket(s) detected." <<endl;
}
25. 9. BRACKET MATCHING
Stacks 25
Input: ( ( ) ())
Read and
push 1st (
(
(
( (
(
( (
Initial empty
stack
Read and
push 2nd (
Read 1st )
and pop (
Read and
push 3rd (
Read 2nd )
and pop (
Read 3rd ) and
pop last (
26. 10. Evaluating Arithmetic (Infix) Expressions
Numbers: push onto the number stack
Operators: push onto the operator’s stack
Right parenthesis, ‘)’: take the two top numbers
from the number stack and the top operator form the
operator’s stack, the two numbers are evaluated and
the result is pushed back to the numbers stack.
Left parenthesis, ‘(‘: throw away.
Input: ( ( ( 6 + 9 ) / 3 ) * ( 6 – 4 ) )
Stacks 26
9
6 +
6+9=15
15
28. 10. Evaluating Arithmetic (Infix) Expressions
Input: ( ( ( 6 + 9 ) / 3 ) * ( 6 – 4 ) )
Stacks 28
2
5 *
2*5=10
10
At this point, there is no more input, and there is
only one number in the numbers stack, so:
10 is the output
29. 11. Evaluating Postfix Expressions
Input: 5 3 2 * + 4 - 5 +
5
7 12
Stacks 29
5
3
5
2
3
5
6
5 11
4
11 7
The result of the computation is: 12
30. 11. Evaluating Postfix Expressions
Pseudocode to evaluate postfix:
1. Initialize a stack of numbers
2. Do
Stacks 30
If (the input is a number)
Push onto the stack
Else
Use top and pop to get the two numbers off the stack
Evaluate the two numbers using the operator
(use the second number popped as the left operand)
Push the result back onto the stack
While (there is more input to read)
3. Pop the only number off the stack, which is the value of the postfix
expression
Input: 5 3 2 * + 4 - 5 +
31. 12. Converting Infix into Postfix Expressions
If the Infix is fully parenthesized:
move each operator to the location of the right
parenthesis corresponding to that operator and then
remove all parenthesis.
Stacks 31
Example:
Infix: ( ( ( A + 7 ) * ( B / C ) ) – ( 2 * D ) )
Postfix: A 7 + B C / * 2 D * –
32. 12. Converting Infix into Postfix Expressions
If the Infix is fully parenthesized (pseudocode):
1. Initialize a stack of characters
2. Do
Stacks 32
If (input is ‘(‘ )
Push onto the stack
Else if (input is a number or operand (A,B,C,…) )
Write to the output
Else if (input is an operator (*, /, + ,-) )
Push onto the stack
Else if (input is ‘)’ )
Discard ‘)’
Write top of stack to the output
Pop the stack (an operator)
Pop the stack (‘(‘)
While (there is more input)
3. At this point the stack should be empty otherwise print error message.
33. 12. Converting Infix into Postfix Expressions
If the Infix is fully parenthesized (pseudocode):
Infix: ( ( ( A + 7 ) * ( B / C ) ) – ( 2 * D ) )
A7+BC/*
/
(
*
(
(
A7+BC/
/
(
*
(
(
Stacks 33
(
(
(
(
(
(
Output: A
+
(
(
(
A 7
+
(
(
(
A 7 +
*
(
(
(
*
(
(
A7+B
A7+BC
*
(
(
34. 12. Converting Infix into Postfix Expressions
If the Infix is fully parenthesized (pseudocode):
Infix: ( ( ( A + 7 ) * ( B / C ) ) – ( 2 * D ) )
A7+BC/*2D*
–
(
Stacks 34
–
(
(
–
( A7+BC/*2
*
(
–
(
A7+BC/*2D
*
(
–
(
A7+BC/*2D*-
35. 12. Converting Infix into Postfix Expressions
If the infix expression is NOT fully parenthesized
+
3X*Y 12-+
Infix: 3 * X + ( Y – 12 ) – Z
–
(
+
3X*Y 12-
–
(
+
Stacks 35
3X*
3
*
3X
* +
(
+
3X*Y
3X*Y 12
–
–
3X*Y 12-+Z –
36. 12. Converting Infix into Postfix Expressions
If the infix expression is NOT fully parenthesized (pseudocode)
Stacks 36
1. Initialize a stack of characters
2. Do
If (input is ‘(‘ )
Push onto the stack
Else if (input is a number or operand (A,B,C,…) )
Write to the output
Else if (input is an operator (*, /, + ,-) )
if the p(top) > p(input)do
push input onto the stack
else
print top of stack and pop
push input
Else if (input is ‘)’ )
Discard ‘)’
Write top of stack to the output,
(keep printing and poping until ‘(‘ is encountered)
While (there is more input)
3. At this point the stack should be empty otherwise print error message.
37. NOTES
Common uses of stack in computer
science:
To keep track of function calls
To keep track of local variables
To analyze syntax of a program
Stacks 37