Lecture 07
Abstract Data Type Stack and Queue (Array-
based Implementation]
CSE225: Data Structures and Algorithms
Stack
▪ A list
▪ Data items can be added and deleted
▪ Maintains Last In First Out (LIFO) order
Specification of StackType
Structure: Elements are added to and removed from the top of the stack.
Definitions (provided by user):
MAX_ITEMS Maximum number of items that might be on the stack.
ItemType Data type of the items on the stack.
Operations (provided by the ADT):
MakeEmpty
Function Sets stack to an empty state.
Postcondition Stack is empty.
Boolean IsEmpty
Function Determines whether the stack is empty.
Precondition Stack has been initialized.
Postcondition Returns true if stack is empty and false otherwise.
Boolean IsFull
Function Determines whether the stack is full.
Precondition Stack has been initialized.
Postcondition Returns true if stack3 is full and false otherwise.
Specification of StackType
Push(ItemType newItem)
Function Adds newItem to the top of the stack.
Precondition Stack has been initialized.
Postcondition If (stack is full), exception FullStack is thrown, else newItem is at
the top of the stack.
Pop()
Function Removes top item from the stack.
Precondition Stack has been initialized.
Postcondition If (stack is empty), exception EmptyStack is thrown, else top
element has been removed from stack.
ItemType Top()
Function Returns a copy of the top item on the stack.
Precondition Stack has been initialized.
Postcondition If (stack is empty), exception EmptyStack is thrown, else a copy of
the top element is returned.
4
stacktype.h
#ifndef STACKTYPE_H_INCLUDED
#define STACKTYPE_H_INCLUDED
const int MAX_ITEMS = 5;
class FullStack
{}; // Exception class thrown by Push when stack is full.
class EmptyStack
{}; // Exception class thrown by Pop and Top when stack is empty.
template <class ItemType>
class StackType
{
public:
StackType();
bool IsFull();
bool IsEmpty();
void MakeEmpty();
void Push(ItemType);
void Pop();
ItemType Top();
private:
int top;
ItemType items[MAX_ITEMS];
};
#endif // STACKTYPE_H_INCLUDED
5
[Link]
#include "StackType.h" template <class ItemType>
template <class ItemType> void StackType<ItemType>::Push(ItemType
newItem)
StackType<ItemType>::StackType() {
{
if( IsFull() )
top = -1;
} throw FullStack();
template <class ItemType> top++;
bool StackType<ItemType>::IsEmpty() items[top] = newItem;
{ }
return (top == -1); template <class ItemType>
} void StackType<ItemType>::Pop()
void StackType<ItemType>::MakeEmpty() {
{ if( IsEmpty() )
top = -1;
throw EmptyStack();
}
template <class ItemType> top--;
bool StackType<ItemType>::IsFull() }
{ template <class ItemType>
return (top == MAX_ITEMS-1); ItemType StackType<ItemType>::Top()
} {
if (IsEmpty())
throw EmptyStack();
return items[top];
}
6
[Link]
#include "StackType.h" template <class ItemType>
template <class ItemType> void StackType<ItemType>::Push(ItemType
newItem)
StackType<ItemType>::StackType() {
{
if( IsFull() )
}
top = -1;
O(1) throw FullStack();
template <class ItemType>
bool StackType<ItemType>::IsEmpty()
top++;
items[top] = newItem;
O(1)
{ }
}
return (top == -1); O(1) template <class ItemType>
void StackType<ItemType>::Pop()
void StackType<ItemType>::MakeEmpty() {
{ if( IsEmpty() )
}
top = -1; O(1) throw EmptyStack(); O(1)
template <class ItemType> top--;
bool StackType<ItemType>::IsFull() }
{ template <class ItemType>
return (top == MAX_ITEMS-1); ItemType StackType<ItemType>::Top()
} {
O(1) if (IsEmpty())
throw EmptyStack();
return items[top]; O(1)
}
7
Application of Stack
()
(())()(()())()
(())()((()
(())))((()
Which of the strings of parentheses are balanced?
8
Application of Stack
Algorithm for matching parentheses string
1. Initialise an empty stack
2. Read next item in the string
a) If item is an opening parentheses, push it into the stack
b) Else, if item is a closing parentheses, pop from stack
3. If there are more items to process, go to step 2
4. Pop the answer off the stack.
Application of Stack
(())()(()())()
10
Application of Stack
(())()(()())()
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack
11
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack (
12
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack ( (
13
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack (
14
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack
15
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack (
16
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack
17
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack (
18
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack ( (
19
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack (
20
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack ( (
21
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack (
22
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack
23
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack (
24
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack
25
Application of Stack
string ( ( ) ) ( ) ( ( ) ( ) ) ( )
stack
empty stack
Indicates balanced string of parentheses
26
Application of Stack
(())()((()
Consider this string. After processing each
item, the stack is not empty.
stack ( (
non-empty stack
Indicates unbalanced string of parentheses
27
Application of Stack
(())))((()
Consider this string. When processing indicated item,
you are trying to pop from empty stack.
stack
unsuccessful pop
Indicates unbalanced string of parentheses
28
Application of Stack
Evaluating arithmatic expressions
Infix Postfix Evaluation
2-3*4+5 234*-5+ -5
(2 - 3) * (4 + 5) 23-45+* -9
2- (3 * 4 +5) 234*5+- -15
Why ? No parentheses necessary !
Application of Stack
Algorithm for Infix to Postfix
1. Examine the next element in the input.
2. If it is operand, output it.
3. If it is opening parenthesis, push it on stack.
4. If it is an operator, then
• Pop until the top of the stack has an element of lower
precedence
• Then push it
5. If it is a closing parenthesis, pop operators from stack and output them
until an opening parenthesis is encountered. pop and discard the opening
parenthesis.
6. If there is more input go to step 1
7. If there is no more input, pop the remaining operators to output.
30
Application of Stack
Suppose we want to convert
(4+8)*(6-5)/((3-2)*(2+2))into Postfix form
31
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack
Postfix
32
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack (
Postfix
33
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack (
Postfix 4
34
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack ( +
Postfix 4
35
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack ( +
Postfix 4 8
36
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack
Postfix 4 8 +
37
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack *
Postfix 4 8 +
38
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack * (
Postfix 4 8 +
39
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack * (
Postfix 4 8 + 6
40
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack * ( -
Postfix 4 8 + 6
41
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack * ( -
Postfix 4 8 + 6 5
42
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack *
Postfix 4 8 + 6 5 -
43
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack /
Postfix 4 8 + 6 5 - *
44
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / (
Postfix 4 8 + 6 5 - *
45
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( (
Postfix 4 8 + 6 5 - *
46
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( (
Postfix 4 8 + 6 5 - * 3
47
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( ( -
Postfix 4 8 + 6 5 - * 3
48
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( ( -
Postfix 4 8 + 6 5 - * 3 2
49
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / (
Postfix 4 8 + 6 5 - * 3 2 -
50
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( *
Postfix 4 8 + 6 5 - * 3 2 -
51
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( * (
Postfix 4 8 + 6 5 - * 3 2 -
52
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( * (
Postfix 4 8 + 6 5 - * 3 2 - 2
53
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( * ( +
Postfix 4 8 + 6 5 - * 3 2 - 2
54
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( * ( +
Postfix 4 8 + 6 5 - * 3 2 - 2 2
55
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack / ( *
Postfix 4 8 + 6 5 - * 3 2 - 2 2 +
56
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack /
Postfix 4 8 + 6 5 - * 3 2 - 2 2 + *
57
Application of Stack
Infix ( 4 + 8 ) * ( 6 - 5 ) / ( ( 3 - 2 ) * ( 2 + 2 ) )
Stack
Postfix 4 8 + 6 5 - * 3 2 - 2 2 + * /
58
Application of Stack
Now let’s evaluate this expression.
4 8 + 6 5 - * 3 2 – 2 2 + * /
59
Application of Stack
Algorithm for evaluating a postfix expression
1. Initialise an empty stack
2. Read next item in the expression
a) If item is an operand, push it into the stack
b) Else, if item is an operator, pop top two items off the stack, apply
the operator, and push the answer back into the stack
3. If there are more items to process, go to step 2
4. Pop the answer off the stack.
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack
61
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 4
62
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 4 8
63
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12
64
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 6
65
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 6 5
66
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 1
67
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12
68
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 3
69
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 3 2
70
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 1
71
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 1 2
72
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 1 2 2
73
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 1 4
74
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 12 4
75
Application of Stack
string 4 8 + 6 5 - * 3 2 - 2 2 + * /
stack 3
76
Application of Stack
Only item in stack: indicates valid expression
stack 3
More than one item in stack or unsuccessful pop:
indicates invalid expression
77
Queue
• A list
• Data items can be added and deleted
• Maintains First In First Out (FIFO) order
Specification of QueueType
Structure: Elements are added to the rear and removed from the front of the
queue.
Definitions (provided by user):
MAX_ITEMS Maximum number of items that might be on the queue.
ItemType Data type of the items on the queue.
Operations (provided by the ADT):
MakeEmpty
Function Sets stack to an empty state.
Postcondition Stack is empty.
Boolean IsEmpty
Function Determines whether the stack is empty.
Precondition Stack has been initialized.
Postcondition Returns true if stack is empty and false otherwise.
Boolean IsFull
Function Determines whether the stack is full.
Precondition Stack has been initialized.
Postcondition Returns true if stack is
79 full and false otherwise.
Specification of QueueType
Enqueue(ItemType newItem)
Function Adds newItem to the rear of the queue.
Precondition Queue has been initialized.
Postcondition If (queue is full), FullQueue exception is thrown, else newItem is
at rear of queue.
Dequeue(ItemType& item)
Function Removes front item from the queue and returns it in item.
Precondition Queue has been initialized.
Postcondition If (queue is empty), EmptyQueue exception is thrown and item is
undefined, else front element has been removed from queue
and item is a copy of removed element.
80
Implementation Issues
• Always insert elements at the back of the array.
Implementation Issues
• Maintain two indices: front and rear
• Increment the indices as additions and deletions are performed (rear++ for
addition and front++ for deletion)
Dead
space
Implementation Issues
• Maintain two indices: front and rear
• Make the indices “wrap around” when they reach the end of the array
rear = (rear + 1) % maxQue; //maxQue=size of array
front = (front + 1) % maxQue;
Implementation Issues
• How do we differentiate between the empty
state and the full state?
Implementation Issues
• Let front indicate the index of the array slot preceding
the front element.
• The array slot preceding the front element is reserved
and items are not assigned in that slot.
Implementation Issues
• Full queue when (rear + 1) % maxQue == front
• Empty queue when front == rear
queuetype.h
typedef char ItemType;
class FullQueue
{};
class EmptyQueue
{};
class QueType
{
public:
QueType();
QueType(int max);
~QueType();
void MakeEmpty();
bool IsEmpty();
bool IsFull();
void Enqueue(ItemType newItem);
void Dequeue(ItemType& item);
private:
int front;
int rear;
ItemType* items;
int maxQue;
};
87
[Link]
#include "QueType.h" void QueType::MakeEmpty()
{
QueType::QueType(int max) front = maxQue - 1;
{ rear = maxQue - 1;
maxQue = max + 1;
}
front = maxQue - 1;
rear = maxQue - 1;
items = new bool QueType::IsEmpty()
ItemType[maxQue]; {
} return (rear == front);
}
QueType::QueType()
{ bool QueType::IsFull()
maxQue = 501; {
front = maxQue - 1;
return ((rear+1)%maxQue == front);
rear = maxQue - 1;
items = new }
ItemType[maxQue];
}
QueType::~QueType()
{
delete [] items;
} 88
[Link]
void QueType::Enqueue(ItemType newItem)
{
if (IsFull())
throw FullQueue();
else
{
rear = (rear +1) % maxQue;
items[rear] = newItem;
}
}
void QueType::Dequeue(ItemType& item)
{
if (IsEmpty())
throw EmptyQueue();
else
{
front = (front + 1) % maxQue;
item = items[front];
}
}
89
[Link]
#include "QueType.h" void QueType::MakeEmpty()
{
QueType::QueType(int max) front = maxQue - 1;
{
maxQue = max + 1;
rear = maxQue - 1; O(1)
}
front = maxQue - 1;
rear = maxQue - 1;
items = new
O(1) bool QueType::IsEmpty()
ItemType[maxQue]; {
}
}
return (rear == front); O(1)
QueType::QueType()
{ bool QueType::IsFull()
maxQue = 501; {
front = maxQue - 1;
rear = maxQue - 1; O(1) }
return ((rear+1)%maxQue == front);
items = new
ItemType[maxQue]; O(1)
}
QueType::~QueType()
{
delete [] items;
} O(1)
[Link]
void QueType::Enqueue(ItemType newItem)
{
if (IsFull())
throw FullQueue();
else
{
rear = (rear +1) % maxQue;
items[rear] = newItem;
} O(1)
}
void QueType::Dequeue(ItemType& item)
{
if (IsEmpty())
throw EmptyQueue();
else
{
front = (front + 1) % maxQue;
item = items[front];
}
} O(1)
An Application of Queue
• You want to form a number N as a summation of smaller
numbers
• You can only use three prime numbers; 2, 3 and 5
• You can use any of these three prime numbers as many
times as you want
• Can you find the minimum number of prime numbers
required to do this?
An Application of Queue
• Say N = 11
• Possible solutions
• 2+2+2+5
• 3+3+5
• 2+2+2+2+3
An Application of Queue
N = 11
queue
cost
0
An Application of Queue
N = 11
queue
cost
0
An Application of Queue
N = 11
queue
0 2 3 5
cost
0 1 1 1
An Application of Queue
N = 11
queue
0 2 3 5
cost
0 1 1 1
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7
cost
0 1 1 1 2 2 2
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7
cost
0 1 1 1 2 2 2
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8
cost
0 1 1 1 2 2 2 2 2 2
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8
cost
0 1 1 1 2 2 2 2 2 2
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10
cost
0 1 1 1 2 2 2 2 2 2 2 2 2
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10
cost
0 1 1 1 2 2 2 2 2 2 2 2 2
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9 7 8 10
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9 7 8 10
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9 7 8 10 9
10 12
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9 7 8 10 9
10 12
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9 7 8 10 9
10 12 7 8 10
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
3 3 3 3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9 7 8 10 9
10 12 7 8 10
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
3 3 3 3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9 7 8 10 9
10 12 7 8 10 8 9 11
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3
An Application of Queue
N = 11
queue
0 2 3 5 4 5 7 5 6 8 7 8 10 6 7 9 7 8 10 9
10 12 7 8 10 8 9 11
cost
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3