Chapter 5 Stack and Queue
Chapter 5 Stack and Queue
2
Stack
• Linked list and arrays allow one to insert and delete elements
at any place in the list
– At the beginning
– At the end or
– In the middle
4
Stack
5
Stack
6
7
Stack
– Piles
– To be addressed later
8
Stack
9
Stack
• pop (get)
– Is a term used to delete or remove an element or data
from the top of the stack
– Could be written as a function to remove the top entry
– No need to define the element to be removed in case of
pop because there is only one element to be removed, the
element at the top
– No need to use parameter for pop operation
– By default pop operation takes (or removes) the top
element
– Is the synonym for delete when it comes to stack
10
Stack
• To access any entry other than the top one, the program must
remove entries one at a time form the top until the desired
entry is reached
11
Implementation of stacks
– Linked lists
• There are a set of operations that will work with either type of
implementation (push, pop, peek, isEmpty, isFull, sizeOfStack)
12
Array representation of Stacks
• Let MAXSTK
– be the maximum number of elements that can be held by
the stack
– Capacity of the stack
– Array implementation requires this constant because it
uses a fixed size array to hold the items of the stack
– The linked list implementation will use dynamic memory
instead and such a constant is not required
13
Array representation of Stacks
int STACK[MAXSTK];
• This implies TOP will contain the index of the top element of
the stack
14
Array representation of Stacks
15
Stack Errors
• Stack overflow
16
Stack Errors
• Stack Underflow
17
To push or store an element into the stack
• do the following
– Check if there is enough space
• In order to store data
– TOP must be <= MAXSTK – 2 or
– TOP must be < MAXSTK – 1
• because to store on the top, the top must be empty
– If yes increment TOP and then store the element in
STACK[TOP]
• (incrementing must be done before storing/pushing the element)
– If no, No space in the stack and send an overflow message
(stack overflow)
• We use the operation push
18
push Operation
19
push Operation
• Algorithm
20
push Operation
• Remark
22
Push Operation
• C++ implementation
– Include F
– See stack2.cpp
– See stackz.cpp
23
To POP or remove an element from the stack
• do the following
– Check if there is data in the stack (how?)
• Check if TOP > = 0
– If yes
• There is at least one element
• Copy/remove the element in STACK[TOP]
• Then decrement the value of the TOP
– If NO
• No element in the stack
• Send stack underflow message
• We use the operation pop()
24
pop Operation
• The data type of the pop function is the same as the type of
the STACK itself, in this case the type of the array
25
pop Operation
– Step 1
if the stack is empty
give the alert “Stack Underflow!” and quit
else
go to step 2
− Step 2
i. Hold the value for the element pointed by the TOP
ii. Put a NULL value instead
iii. Decrement the TOP by 1
26
pop Operation
/* This procedure deletes the top element of the stack and assigns it
to the variable ITEM*/
DataType pop(STACK, TOP, ITEM)
{
// Stack has item to be removed?
If(TOP==-1)
cout<<“\nUNDERFLOW” ; //print UNDERFLOW and return (TOP);
else
{
ITEM=STACK[TOP]; // Assign (set) top element to ITEM
STACK[TOP]=NULL;
TOP=TOP – 1;//TOP is decreased by 1. The value of TOP, in case
//of pop, is changed after the deletion in pop
}
return (ITEM);
}
27
pop Operation
• Remark
28
pop Operation
• C++ implementation
– Include G
29
isEmpty() & isFULL()
30
peek()
– Include E
31
sizeOfStack()
32
Linked List Implementation of Stack
• 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
33
Linked List Implementation of Stack
node * headPtr=NULL;
node *topPtr=NULL;
34
Defining the Structure
struct number {
int num;
number *next;
}
number * bottomPtr =NULL;
number * topPtr=NULL;
35
To push an element
36
To push an element
– Create a link between the last node and the newly created
node.
• That is, the next pointer of the last node in the list
should point to the newly created node
• Algorithm
– Step 3- create the new element and make the last (top
most) element of the stack to point to it
– Include H
– See stack5.cpp
39
Linked list implementation of stacks:
push operation
• Remarks
– The only difference here is that you can add the new
element only at the end of the list, which means additions
can happen only from the TOP
– Since dynamic list is used for the stack, the stack is also
dynamic, means it has no prior upper limit
41
To pop an element
• Algorithm
1. If the stack is empty then give an alert message “stack
Underflow” and quite; or else proceed
43
Linked list implementation of stacks:
pop operation
– Include I
– See stack5.cpp
44
Linked list implementation of stacks:
pop operation
• The pop operation is similar to the deletion operation in any
linked list but you can only delete from the end of the list and
only one at time
• Every time we pop, the TOP most element will be deleted and
targetPtr will be made as the top most element
• Supposing you have only one element left in the stack, then
we won’t make use of targetPtr. Rather we will take help of
bottomPtr
45
Stack Applications
46
Applications of Stacks
Infix to Postfix (RPN) Conversion
Types of Expression
• Notations for Arithmetic Expression
• There are three notations to represent an arithmetic
expression:
• Infix Notation
• Prefix Notation
• Postfix Notation
• The normal (or human) way of expressing mathematical expressions
is called infix form, e.g. 4+5*5.
47
Prefix Notation(Polish notation)
• The prefix notation places the operator before the
operands. This notation was introduced by the Polish
mathematician and hence often referred to as polish
notation.
48
Postfix Notation(Reverse Polish notation)
• The postfix notation places the operator after
the operands.
• This notation is just the reverse of Polish
notation and also known as Reverse Polish
notation.
e.g. 4 5 5 * +
49
Transforming Infix to Postfix
Goal is show you how to evaluate infix
algebraic expression, postfix expressions are
easier to evaluate.
So first look at how to represent an infix
expression by using postfix notation.
Infix Postfix
a+b ab+
(a+b)*c ab+c*
a + b*c abc*+
50
Pencil and paper scheme
We write the infix expression with a fully
parenthesized infix expression.
For example: (a+b)*c as ((a+b)*c). Each operator is
associated with a pair of parentheses.
Now we move each operator to the right, so it
appears immediately before its associated close
parenthesis:
((ab+)c*)
Finally, we remove the parentheses to obtain the
postfix expression. ab+c*
51
infix Notation Prefix Notation Postfix Notation
A*B *AB AB*
(A+B)/C /+ ABC AB+C/
(A*B) + (D-C) +*AB - DC AB*DC-+
Exercise
a+b*c
a * b / (c - d)
a / b + (c - d)
a/b+c-d
52
Answers
abc*+
ab*cd-/
ab/cd-+
ab/c+d-
Infix to Postfix (RPN) Conversion
• Scan the infix expression from left to right.
• Encounter an operand, place it at the end of new
expression.
• Encounter an operator, save the operator until the right
time to pop up
– Depends on the relative precedence of the next operator.
• Higher precedence operator can be pushed
• Same precedence, operator gets popped.
58
Operator Precedence (for this algorithm):
59
Converting infix expression to postfix form:
a ^ b ^ c
An exception: if an operator is ^,
push it onto the stack regardless of
what is at the top of the stack
• Infix-to-Postfix Algorithm
Symbol in
Action
Infix
Operand Append to end of output expression
Operator ^ Push ^ onto stack
Operator +,-, Pop operators from stack, append to output
*, or / expression until stack empty or top has
lower precedence than new operator. Then
push new operator onto stack
Open Push ( onto stack, treat it as an operator
parenthesis with the lowest precedence
Close Pop operators from stack, append to output
parenthesis expression until we pop an open
parenthesis. Discard both parentheses.
Steps to convert the infix expression
a / b * ( c + ( d – e ) ) to postfix form.
(a + b)/(c - d)
a / (b - c) * d
a-(b / (c-d) * e + f) ^g
(a – b * c) / (d * e ^ f * g + h)
Answer
ab+cd-/
abc-/d*
abcd-/e*f + g^-
abc* -def^*g*h+/
Example:
Convert to postfix expression:
a) 4 + 3*(6*3-12)
b) A + B * C + D
c) (A + B) * (C + D)
d) A+(B*C+D)/E
e) 10 + 3 * 5 / (16 - 4)
65
Postfix Evaluation
Consider the postfix expression :
6523+8*+3+*
66
Evaluating Postfix Expression
• Save operands until we find the operators that apply to
them.
• When see operator, is second operand is the most
recently save value. The value saved before it – is the
operator’s first operand.
• Push the result into the stack. If we are at the end of
expression, the value remains in the stack is the value of
the expression.
Algorithm
initialise stack to empty;
while (not end of postfix expression) {
get next postfix item;
if(item is value)
push it onto the stack;
else if(item is binary operator) {
pop the stack to x;
pop the stack to y;
perform y operator x;
push the results onto the stack;
}
else if (item is unary operator) {
pop the stack to x;
perform operator(x);
push the results onto the stack
} The single value on the stack is the desired result .
68
}
• The stack during the evaluation of the postfix
expression a b / when a is 2 and b is 4
Unary operators: unary minus, square root, sin, cos, exp, etc.,
Example:
Evaluate:
a) 6 5 2 3 + 8 * + 3 + *
b) 4 5 + 7 2 - *
c) 4 2 3 5 1 - + * +
70
The stack during the evaluation of the postfix expression
a b + c / when a is 2, b is 4 and c is 3
Exercise:
Evaluate the following postfix expression.
Assume that a=2, b=3, c=4, d=5, and e=6
ae+bd-/
abc*d*-
abc-/d*
ebca^*+d-
Application of stack:
Balanced parentheses using Stack
73
Steps to find whether a given expression is balanced or unbalanced
74
75
Stack in function calls
• Program Stack: Program Stack is the stack which holds all
the function calls, with bottom elements as the main
function.
• Stack Frame: Stack Frame is actually a buffer memory that
is an element of program stack and has data of the called
function ie
– Return Address
– Input Parameter
– Local Variables
78
Queue
• That is, it is a data structure that has access to its data at the
front and rear
79
Queue
– That is, the first element inserted into a queue is the first
element to be removed
80
Queue
81
Queue
– empty(q)
• Returns false or true depending on whether or not the queue
contains any elements
82
Queue
• Example
Operation Content of queue
Enqueue(q, B)
Enqueue(q, C)
Enqueue(q)
Enqueue(q, G)
Enqueue(q, F)
Enqueue(q)
Enqueue(q, A)
Enqueue(q)
83
Queue
– As an array
– As a linked list
84
Simple array representation of queue
int QUEUESIZE = 0
• Remark
– Using an array to hold a queue introduces the
possibility of overflow if the queue should grow larger
than the size of the array
86
Simple array representation of queue
87
Simple array representation of queue
88
Simple array representation of queue
• Algorithm to dequeue data from the queue
– Check if there is data in the queue
– To do this ask this question
• Is QUEUESIZE > 0 ?
– If (QUEUESIZE > 0) is true
• Copy the data in queue[FRONT]
• Increment FRONT by 1
• Decrement QUEUESIZE by 1
– If (QUEUESIZE > 0) is false
• Display the message “Queue Underflow”
89
C++ implementation of enqueue and equeue
int QUEUESIZE = 0;
90
C++ implementation of enqueue and equeue
void enqueue(char queue[], char x)
{
if(REAR < MAX_SIZE - 1)
{
REAR++;
queue[REAR] = x;
QUEUESIZE++;
if(FRONT = = -1)
FRONT++;
}
else
cout<<"Queue Overflow";
}
91
C++ implementation of enqueue and equeue
int dequeue(char queue[])
{
char x;
if(QUEUESIZE>0)
{
x=queue[FRONT];
FRONT++;
QUEUESIZE--;
}
else
cout<<"Queue Underflow";
return (x);
}
92
Array representation of queue
• Example 1
– Answer
• See queue3.cpp
93
Simple array representation of queue
94
Limitation of simple array representation of queue
• The array representation outlined earlier has a limitation
– The variable rear is incremented but never decremented
– Hence, it will quickly reach the end of the array
– At that point, we will not be able to add any more elements
to the queue, yet there is likely to be room in the array
– In fact, it is possible to reach the absurd situation where the
queue is empty, yet no new element can be inserted
– In normal application, the variable front would also be
incremented from time to time (when entries are removed
from the queue)
– This will free up the array application with index values less
than front
• Different solutions to overcome this problem
95
Solution 1
• For using the freed array locations
96
Solution 1
• Modify the dequeue operation so that when an item is deleted,
the entire queue is shifted to the beginning of the array
x=queue(FRONT);
for(int i = 0; i < REAR; i++)
{
queue[i] = queue[i+1];
}
REAR--;
97
Solution 1 …
• The queue need no longer contain a front field
98
Solution 1 …
• Is this method efficient?
– The method will work
– But, it is not efficient, in fact too inefficient
– Each deletion involves moving every remaining element of
the queue
– Every time we remove an entry from the queue, we must
move every entry in the queue
– If a queue contains 500 or 100 elements, this is high a price
to pay
– Further, the operation of removing an element from a queue
logically involves manipulation of only one element
– The implementation of that operation should reflect this and
should not involve a host of extraneous operations
99
Solution 1 …
• Exercise
100
Solution 2
• Is a better approach
• When the rear index reaches the end of the array, we can
simply start using the variable locations at the front
• That is, the successor of the last array index is the first array
index
101
Solution 2…
• In this arrangement (circular queue), the free index positions
are always to the “right after” queue[REAR]
• Example
– See also D
102
Solution 2 …
103
Solution 2 …
• With this view, the queue’s entries start at queue[FRONT] and
continue forward
• If you reach the end of the array, then come back at queue[0],
and keep going until you find the REAR
• It may help to actually view the array as bent circle, with the
final array element attached back to the front as shown below
• 104
• Incude diagram and the statement just above it on kinfe
• See also mu not
12 11
13
10
9
MAX_SIZE - 1 8
0 7
1 6
2 5
3 4
105
Circular array implementation of queue
• Consider the structure queue[QUEUESIZE]
108
C++ implementation of enqueue and equeue
(circular array of queue)
109
C++ implementation of enqueue and equeue
(Circular array of queue)
void enqueue(int x)
{
if(QUEUESIZE<MAX_SIZE)
{
REAR++;
if(REAR = = MAX_SIZE)
REAR=0;
Num[REAR]=x;
QUEUESIZE++;
if(FRONT = = -1)
FRONT++;
}
else
cout<<"Queue Overflow";
}
110
C++ implementation of enqueue and equeue
(Circular array of queue)
int dequeue()
{
int x;
if(QUEUESIZE>0)
{
x=Num[FRONT];
FRONT++;
if(FRONT = = MAX_SIZE)
FRONT = 0;
QUEUESIZE--;
}
else
cout<<"Queue Underflow";
return(x);
}
111
C++ implementation of enqueue and equeue
(Circular array of queue)
• Example 3
– Answer
• See queue5.cpp
112
C++ implementation of enqueue and equeue
(Circular array of queue)
113
C++ implementation of enqueue and equeue
(Circular array of queue)
• Example 4
– See queue6.cpp
114
Linked list implementation of enqueue and dequeue
operations
• Enqueue- is inserting a node at the end of a linked list
• Dequeue- is deleting the first node in the list
• Define the structure to hold references to queue nodes for the
linked queue implementation
struct queue {
char item;
queue next
};
115
Linked list implementation of enqueue operation
/* Adds item to the rear of this queue */
void enqueue(char x)
{
queue * temp = new queue;
if(temp == NULL)
cout<<“\nQueue is FULL”;
temp->item = x;
temp -> next = NULL;
to be checked
if(rearPtr == NULL)
frontPtr=temp;
else
rearPtr -> next = temp;
rearPtr = temp;
}
116
Linked list implementation of dequeue operation
/* Removes front element form this queue and return it */
void dequeue()
{
char data;
return data;
}
117
Linked list implementation of enqueue and dequeue
operations
• Example
– queue7.cpp
– Queue8.cpp
118
Deque (pronounced as Deck)
• Is a Double Ended Queue
Front Rear
120
Deque (pronounced as Deck)
• Example
– Queue9.cpp
• Exercise
• Examples
• If there are several entries with equal high priorities, then the
one that was placed in the priority queue first is the one
removed first
123
Priority Queue
• That is, in priority queues, elements are dequeued according to
124
Priority Queue
• A wide spectrum of possible criteria can be used to prioritize
elements in different cases
– Frquency of use
– Birth date
– Salary
– Postion
– Status
– gender
125
Priority queue enqueue and dequeue operations
• Dequeue operation deletes data having highest priority in
the list
• Example:
126
Priority queue enqueue and dequeue operations
• Dequeue() deletes Aster
• Now the queue has data having equal priority and dequeue
operation deletes the front element like in the case of ordinary
queues.
127
Priority queue enqueue and dequeue operations
128
Types of Priority queues
• There are two types of priority queues, ascending priority
queue and descending priority queue
129
Ascending Priority Queue
• Is a collection of items into which items can be inserted
arbitrarily and from which only the smallest item can be
removed
130
Descending Priority Queue
• Is a collection of items into which items can be inserted
arbitrarily and from which only the largest item can be
removed
131
Priority queue
• Examples
– Queue10.cpp (array implementation)
– Queue11.cpp (ascending priority)
• Linked list implementation
– Queue12.cpp (descending priority)
• Linked list implementation
– Queue13.cpp
• Linked list implementation
– Queue14.cpp
• Linked list implementation
– Queue15.cpp
• Linked list implementation
132
Reading assignment
• Demerging queues
• Merging queues
• Application of queues
– Page 61
133
134
135