0% found this document useful (0 votes)
27 views

Unit-3 21CSC201J

Uploaded by

numblopunguri
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views

Unit-3 21CSC201J

Uploaded by

numblopunguri
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

21CSC201J – DATA STRUCTURES AND ALGORITHMS

Unit-3
Stack and Queue
Operations on Stack ADT – Create, Push, Pop, Top; Implementation of Stack ADT – Array and
Linked; Applications - Infix to Postfix Conversion, Postfix Evaluation, Balancing symbols,
Function Calls, Tower of Hanoi; Operations on Queue ADT - Create, Enqueue and Dequeue;
Implementation of Queue ADT – Array and Linked; Types of Queue - Circular, Double ended
and Priority Queue, Applications – Scheduling

Operations on Stack ADT – Create, Push, Pop, Top; Implementation of Stack


ADT – Array and Linked
STACK:
• A stack is a linear data structure which uses the same principle, i.e., the elements in a
stack are added and removed only from one end, which is called the TOP. Hence, a
stack is called a LIFO (Last-In-First-Out) data structure, as the element that was
inserted last is the first one to be taken out
• Stack stores its elements in an ordered manner. Example: Stack of Plates, when you
want to remove a plate, you remove the topmost plate first. Hence, you can add and
remove an element (i.e., a plate) only at/from one position which is the topmost
position.
• Stacks can be implemented using either arrays or linked lists.

Figure: Stack of plates

ARRAY REPRESENTATION OF STACKS


• In the computer’s memory, stacks can be represented as a linear array. Every stack has
a variable called TOP associated with it, which is used to store the address of the
topmost element of the stack. It is this position where the element will be added to
or deleted from.
• There is another variable called MAX, which is used to store the maximum number of
elements that the stack can hold. If TOP = NULL, then it indicates that the stack is
empty and if TOP = MAX–1, then the stack is full. (It is written MAX–1, because array
indices start from 0.)

Figure : Stack

CODING GEEKZ (Dr.S.Priya) 1


• The stack in the above Figure shows that TOP = 4, so insertions and deletions will be
done at this position. In the above stack, five more elements can still be stored.
OPERATIONS ON A STACK

• A stack supports three basic operations: push, pop, and peek.


• The push operation adds an element to the top of the stack and the pop operation
removes the element from the top of the stack. The peek operation returns the value
of the topmost element of the stack.
Push Operation:

• The push operation is used to insert an element into the stack.


• The new element is added at the topmost position of the stack. However, before
inserting the value, we must first check if TOP=MAX–1, because if that is the case, then
the stack is full and no more insertions can be done.
• If an attempt is made to insert a value in a stack that is already full, an OVERFLOW
message is printed.

Figure: Stack
• To insert an element with value 6, we first check if TOP=MAX–1. If the condition is
false, then we increment the value of TOP and store the new element at the position
given by stack[TOP]. Thus, the updated stack becomes as shown in Figure below.

Figure: Stack after insertion


Algorithm:

Figure: Algorithm to insert an element in a stack

• In Step 1, we first check for the OVERFLOW condition.


• In Step 2, TOP is incremented so that it points to the next location in the array.
• In Step 3, the value is stored in the stack at the location pointed by TOP.

CODING GEEKZ (Dr.S.Priya) 2


POP Operation

• The pop operation is used to delete the topmost element from the stack.
• However, before deleting the value, we must first check if TOP=NULL because if that is
the case, then it means the stack is empty and no more deletions can be done.
• If an attempt is made to delete a value from a stack that is already empty, an
UNDERFLOW message is printed.

Figure: Stack

• To delete the topmost element, we first check if TOP=NULL. If the condition is false,
then we decrement the value pointed by TOP. Thus, the updated stack becomes as
shown in the Figure below.

Figure: Stack after deletion


Algorithm:

Figure : Algorithm to delete an element from a stack

• In Step 1, we first check for the UNDERFLOW condition.


• In Step 2, the value of the location in the stack pointed by TOP is stored in VAL.
• In Step 3, TOP is decremented.
Peek Operation

• Peek is an operation that returns the value of the topmost element of the stack
without deleting it from the stack.
• However, the Peek operation first checks if the stack is empty, i.e., if TOP = NULL, then
an appropriate message is printed, else the value is returned.

Figure: Stack

CODING GEEKZ (Dr.S.Priya) 3


• Here, the Peek operation will return 5, as it is the value of the topmost element of
the stack.
Algorithm:

Figure : Algorithm for Peek operation

LINKED REPRESENTATION OF STACKS


In a linked stack, every node has two parts—one that stores data and another that stores the address
of the next node.

The START pointer of the linked list is used as TOP. All insertions and deletions are done at the node
pointed by TOP. If TOP = NULL, then it indicates that the stack is empty.

The linked representation of a stack is shown in the Figure given below.

Figure : Linked stack

OPERATIONS ON A LINKED STACK


A linked stack supports all the three stack operations, that is, push, pop, and peek.
Push Operation

• The push operation is used to insert an element into the stack. The new element is
added at the topmost position of the stack. Consider the linked stack shown in Fig.
given below

Figure: Linked stack

• To insert an element with value 9, we first check if TOP=NULL. If this is the case, then
we allocate memory for a new node, store the value in its DATA part and NULL in its
NEXT part.
• The new node will then be called TOP. However, if TOP!=NULL, then we insert the new
node at the beginning of the linked stack and name this new node as TOP.

CODING GEEKZ (Dr.S.Priya) 4


• Thus, the updated stack becomes as shown in Fig. given below

Figure : Linked stack after inserting a new node

Algorithm:

Figure: Linked stack after inserting a new node

• In Step 1, memory is allocated for the new node.


• In Step 2, the DATA part of the new node is initialized with the value to be stored in
the node.
• In Step 3, we check if the new node is the first node of the linked list. This is done by
checking if TOP = NULL. In case the IF statement evaluates to true, then NULL is stored
in the NEXT part of the node and the new node is called TOP.
• However, if the new node is not the first node in the list, then it is added before the
first node of the list (that is, the TOP node) and termed as TOP.
Pop Operation

• The pop operation is used to delete the topmost element from a stack.
• However, before deleting the value, we must first check if TOP=NULL, because if this is
the case, then it means that the stack is empty and no more deletions can be done.
• If an attempt is made to delete a value from a stack that is already empty, an
UNDERFLOW message is printed. Consider the stack shown in Figure below

Figure: Linked stack

• In case TOP!=NULL, then we will delete the node pointed by TOP, and make TOP point
to the second element of the linked stack. Thus, the updated stack becomes as shown
in Figure below

CODING GEEKZ (Dr.S.Priya) 5


Figure : Linked stack after deletion of the topmost element

Algorithm:

Figure: Algorithm to delete an element from a linked stack

• In Step 1, we first check for the UNDERFLOW condition.


• In Step 2, we use a pointer PTR that points to TOP.
• In Step 3, TOP is made to point to the next node in sequence.
• In Step 4, the memory occupied by PTR is given back to the free pool.
Applications - Infix to Postfix Conversion, Postfix Evaluation, Balancing
symbols, Function Calls, Tower of Hanoi;
APPLICATIONS OF STACK - INFIX TO POSTFIX CONVERSION
• Any expression can be represented using three types of expressions (Infix, Postfix, and
Prefix).
• To convert Infix Expression into Postfix Expression using a stack data structure, We can
use the following steps...
1. Read all the symbols one by one from left to right in the given Infix Expression.
2. If the reading symbol is operand, then directly print it to the result (Output).
3. If the reading symbol is left parenthesis '(', then Push it on to the Stack.
4. If the reading symbol is right parenthesis ')', then Pop all the contents of stack
until respective left parenthesis is poped and print each poped symbol to the
result.
5. If the reading symbol is operator (+ , - , * , / etc.,), then Push it on to the Stack.
However, first pop the operators which are already on the stack that have
higher or equal precedence than current operator and print them to the result.

CODING GEEKZ (Dr.S.Priya) 6


Example: 1
Consider the following Infix Expression...
(A+B)*(C-D)
The given infix expression can be converted into postfix expression using Stack data Structure
as follows...

CODING GEEKZ (Dr.S.Priya) 7


Example: 2
Convert the following infix expression into postfix expression: A – (B / C + (D % E * F) / G)* H

Algorithm:

Figure : Algorithm to convert an infix notation to postfix notation

CODING GEEKZ (Dr.S.Priya) 8


APPLICATIONS OF STACK - EVALUATION OF A POSTFIX EXPRESSION
▪ Using stacks, any postfix expression can be evaluated very easily. Every character of
the postfix expression is scanned from left to right.
▪ If the character encountered is an operand, it is pushed on to the stack. However, if
an operator is encountered, then the top two values are popped from the stack and
the operator is applied on these values. The result is then pushed on to the stack.
Algorithm:

Figure : Algorithm to evaluate a postfix expression


Example:
Consider the infix expression given as 9 – ((3 * 4) + 8) / 4. Evaluate the expression.

Figure : Evaluation of a postfix expression

CODING GEEKZ (Dr.S.Priya) 9


APPLICATIONS OF STACK - BALANCING SYMBOLS
The steps involved to implement the idea of balancing symbol is given below.

▪ Declare a character stack (say temp).


▪ Now traverse the string exp.
o If the current character is a starting bracket ( ‘(‘ or ‘{‘ or ‘[‘ ) then push it to stack.
o If the current character is a closing bracket ( ‘)’ or ‘}’ or ‘]’ ) then pop from the stack
and if the popped character is the matching starting bracket then fine.
▪ Else brackets are Not Balanced.
▪ After complete traversal, if some starting brackets are left in the stack, then the
expression is Not balanced, else Balanced.

Example:

CODING GEEKZ (Dr.S.Priya) 10


APPLICATIONS OF STACK - FUNCTION CALLS
• A recursive function is defined as a function that calls itself to solve a smaller version
of its task until a final call is made which does not require a call to itself.
• Since a recursive function repeatedly calls itself, it makes use of the system stack to
temporarily store the return address and local variables of the calling function.
• Every recursive solution has two major cases. They are
▪ Base case, in which the problem is simple enough to be solved directly without
making any further calls to the same function.
▪ Recursive case, in which first the problem at hand is divided into simpler sub-
parts. Second the function calls itself but with sub-parts of the problem
obtained in the first step. Third, the result is obtained by combining the
solutions of simpler sub-parts.
Example:

• To understand recursive functions, let us take an example of calculating factorial of a


number. To calculate n!, we multiply the number with factorial of the number that is
1 less than that number. In other words, n! = n * (n–1)!

Figure: Recursive factorial function

• Every recursive function must have a base case and a recursive case. For the factorial
function,
▪ Base case is when n = 1, because if n = 1, the result will be 1 as 1! = 1.
▪ Recursive case of the factorial function will call itself but with a smaller value
of n, this case can be given as factorial(n) = n × factorial (n–1)

APPLICATIONS OF STACK - TOWER OF HANOI


• The tower of Hanoi is one of the main applications of stack using recursion. It says, ‘if
you can solve n–1 cases, then you can easily solve the nth case’. Three rings mounted
on pole A as shown in Figure below.

CODING GEEKZ (Dr.S.Priya) 11


Figure : Tower of Hanoi

• The problem is to move all these rings from pole A to pole C while maintaining the
same order. The main issue is that the smaller disk must always come above the
larger disk.
• We will be doing this using a spare pole. In our case, A is the source pole, C is the
destination pole, and B is the spare pole. To transfer all the three rings from A to C, we
will first shift the upper two rings (n–1 rings) from the source pole to the spare pole.
We move the first two rings from pole A to B as shown in Figure below.

Figure : Move rings from A to B

• Now that n–1 rings have been removed from pole A, the nth ring can be easily moved
from the source pole (A) to the destination pole (C). Figure below shows this step.

Figure : Move ring from A to C

• The final step is to move the n–1 rings from the spare pole (B) to the destination pole
(C). This is shown in Figure below.

Figure : Move ring from B to C

CODING GEEKZ (Dr.S.Priya) 12


• To summarize, the solution to our problem of moving n rings from A to C using B as
spare can be given as:
Base case: if n=1
o Move the ring from A to C using B as spare
Recursive case:
o Move n – 1 rings from A to B using C as spare
o Move the one ring left on A to C using B as spare
o Move n – 1 rings from B to C using A as spare T
Code:
The following code implements the solution of the tower of Hanoi problem.

OPERATIONS ON QUEUE ADT - CREATE, ENQUEUE AND DEQUEUE;


QUEUE
• A queue is an important data structure which is extensively used in computer
applications.
• A queue is a FIFO (First-In, First-Out) data structure in which the element that is
inserted first is the first one to be taken out. The elements in a queue are added at one
end called the REAR and removed from the other end called the FRONT.
• Queues can be implemented by using either arrays or linked lists.

IMPLEMENTATION OF QUEUE ADT – ARRAY


• Queues can be easily represented using linear arrays.
• Every queue has front and rear variables that point to the position from where deletions
and insertions can be done, respectively.

CODING GEEKZ (Dr.S.Priya) 13


Figure: Queue (FRONT = 0 and REAR = 5)

• Suppose we want to add another element with value 45, then REAR would be incremented
by 1 and the value would be stored at the position pointed by REAR. Here, FRONT = 0 and
REAR = 6.

Figure : Queue after insertion of a new element

• If we want to delete an element from the queue, then the value of FRONT will be
incremented. Deletions are done from only this end of the queue. The queue after
deletion will be as shown in Figure below. Here, FRONT = 1 and REAR = 6.

OVERFLOW AND UNDERFLOW CONDITION

• Before inserting an element in a queue, we must check for overflow conditions. An


overflow will occur when we try to insert an element into a queue that is already full.
• When REAR = MAX – 1, where MAX is the size of the queue, we have an overflow
condition. Note that we have written MAX – 1 because the index starts from 0.
INSERTION

Figure: Algorithm to insert an element in a queue

• In Step 1, we first check for the overflow condition.

CODING GEEKZ (Dr.S.Priya) 14


• In Step 2, we check if the queue is empty. In case the queue is empty, then both FRONT
and REAR are set to zero, so that the new value can be stored at the 0th location.
Otherwise, if the queue already has some values, then REAR is incremented so that it
points to the next location in the array.
• In Step 3, the value is stored in the queue at the location pointed by REAR.
DELETION

• In Step 1, we check for underflow condition. An underflow occurs if FRONT = –1 or


FRONT > REAR. However, if queue has some values, then FRONT is incremented so that
it now points to the next value in the queue.

Figure: Algorithm to delete an element from a queue

IMPLEMENTATION OF QUEUE ADT – LINKED LIST


• In a linked queue, every element has two parts, one that stores the data and another
that stores the address of the next element.
• The START pointer of the linked list is used as FRONT. Here, we will also use another
pointer called REAR, which will store the address of the last element in the queue.
• All insertions will be done at the rear end and all the deletions will be done at the front
end. If FRONT = REAR = NULL, then it indicates that the queue is empty.

Figure : Linked queue


OPERATIONS ON LINKED QUEUES

• A queue has two basic operations: insert and delete. The insert operation adds an
element to the end of the queue, and the delete operation removes an element from
the front or the start of the queue.
INSERT OPERATION (Enqueue)

• The insert operation is used to insert an element into a queue. The new element is
added as the last element of the queue. Consider the linked queue

Figure : Linked queue

CODING GEEKZ (Dr.S.Priya) 15


• To insert an element with value 9, we first check if FRONT=NULL. If the condition holds,
then the queue is empty. So, we allocate memory for a new node, store the value in
its data part and NULL in its next part.
• The new node will then be called both FRONT and rear. However, if FRONT != NULL,
then we will insert the new node at the rear end of the linked queue and name this
new node as rear. Thus, the updated queue becomes as shown in Figure below.

Figure : Linked queue after inserting a new node


ALGORITHM:

• In Step 1, the memory is allocated for the new node.


• In Step 2, the DATA part of the new node is initialized with the value to be stored in the
node. In Step 3, we check if the new node is the first node of the linked queue. This is done
by checking if FRONT = NULL. If this is the case, then the new node is tagged as FRONT as
well as REAR. Also NULL is stored in the NEXT part of the node (which is also the FRONT
and the REAR node).
• However, if the new node is not the first node in the list, then it is added at the REAR end
of the linked queue (or the last node of the queue).
DELETE OPERATION (Dequeue)

• The delete operation is used to delete the element that is first inserted in a queue, i.e.,
the element whose address is stored in FRONT.
• However, before deleting the value, we must first check if FRONT=NULL because if this
is the case, then the queue is empty and no more deletions can be done.
• If an attempt is made to delete a value from a queue that is already empty, an
underflow message is printed. Consider the queue shown in Figure below:

CODING GEEKZ (Dr.S.Priya) 16


Figure :Linked queue

• To delete an element, we first check if FRONT=NULL. If the condition is false, then we


delete the first node pointed by FRONT. The FRONT will now point to the second
element of the linked queue. Thus, the updated queue becomes as shown in the below
Figure.

Figure : Linked queue after deletion of an element


ALGORITHM:

• In Step 1, we first check for the underflow condition. If the condition is true, then an
appropriate message is displayed, otherwise in Step 2, we use a pointer PTR that points
to FRONT.
• In Step 3, FRONT is made to point to the next node in sequence.
• In Step 4, the memory occupied by PTR is given back to the free pool.

TYPES OF QUEUES
A queue data structure can be classified into the following types:
1. Circular Queue
2. Deque
3. Priority Queue
CIRCULAR QUEUES
Why do we need a Circular Queue?

• In linear queues, insertions can be done only at one end called the REAR and deletions
are always done from the other end called the FRONT. Consider a Queue given below.

CODING GEEKZ (Dr.S.Priya) 17


Figure: Linear queue (FRONT = 0 and REAR = 9)

• Consider a scenario in which two successive deletions are made. The queue will then
be given as shown in the below figure.

Figure: Queue after two successive deletions (FRONT = 2 and REAR = 9)

• Suppose we want to insert a new element in the queue shown in Figure, Even though
there is space available, the overflow condition still exists because the condition rear
= MAX – 1 still holds true. This is a major drawback of a linear queue.
• To resolve this problem, we have two solutions.
o First, shift the elements to the left so that the vacant space can be occupied
and utilized efficiently. But this can be very time-consuming, especially when
the queue is quite large.
o The second option is to use a circular queue. In the circular queue, the first
index comes right after the last index
INSERTION - Implementation of Circular Queue

• The circular queue will be full only when front = 0 and rear = Max – 1.

Figure: Full Queue

• A circular queue is implemented in the same manner as a linear queue is


implemented. For insertion, we now have to check for the following three conditions:
• If front = 0 and rear = MAX – 1, then the circular queue is full.
• If rear != MAX – 1, then rear will be incremented and the value will be inserted.

Figure: Queue with vacant locations

• If Front != 0 and rear = MAX – 1, then it means that the queue is not full. So, set rear =
0 and insert the new element there, as shown in Figure below.

CODING GEEKZ (Dr.S.Priya) 18


Figure : Inserting an element in a circular queue

ALGORITHM - INSERTION

• In Step 1, we check for the overflow condition.


• In Step 2, we make two checks. First to see if the queue is empty, and second to see if
the REAR end has already reached the maximum capacity while there are certain free
locations before the FRONT end.
• In Step 3, the value is stored in the queue at the location pointed by REAR

DELETION - Implementation of Circular Queue

• If front = –1, then there are no elements in the queue. So, an underflow condition will
be reported.
• If the queue is not empty and front = rear, then after deleting the element at the front
the queue becomes empty and so front and rear are set to –1.

Figure: Queue with a single element

• If the queue is not empty and front = MAX–1, then after deleting the element at the
front, front is set to 0. This is shown in Figure below.

CODING GEEKZ (Dr.S.Priya) 19


Figure : Queue where front = MAX–1 before deletion

ALGORITHM – DELETION

• In Step 1, we check for the underflow condition.


• In Step 2, the value of the queue at the location pointed by FRONT is stored in VAL.
• In Step 3, we make two checks. First to see if the queue has become empty after
deletion and second to see if FRONT has reached the maximum capacity of the queue.
• The value of FRONT is then updated based on the outcome of these checks.

Figure : Algorithm to delete an element from a circular queue

DEQUE (DOUBLE-ENDED QUEUES)

• A deque (pronounced as ‘deck’ or ‘dequeue’) is a list in which the elements can be


inserted or deleted at either end.
• It is also known as a head-tail linked list because elements can be added to or removed
from either the front (head) or the back (tail) end.
• However, no element can be added and deleted from the middle. In the computer’s
memory, a deque is implemented using either a circular array or a circular doubly
linked list.

Figure : Double-ended queues

CODING GEEKZ (Dr.S.Priya) 20


• In a deque, two pointers are maintained, LEFT and RIGHT, which point to either end
of the deque. The elements in a deque extend from the LEFT end to the RIGHT end
and since it is circular, Dequeue[N–1] is followed by Dequeue[0].
• There are two variants of a double-ended queue. They include
o Input restricted deque: In this dequeue, insertions can be done only at one of the
ends, while deletions can be done from both ends.
o Output restricted deque: In this dequeue, deletions can be done only at one of the
ends, while insertions can be done on both ends.
PRIORITY QUEUE

• A priority queue is a data structure in which each element is assigned a priority. The
priority of the element will be used to determine the order in which the elements will
be processed.
• The general rules of processing the elements of a priority queue are
o An element with higher priority is processed before an element with a lower
priority.
o Two elements with the same priority are processed on a first-come-first-served
(FCFS) basis.
Implementation of a Priority Queue

• There are two ways to implement a priority queue. We can either use a sorted
list to store the elements so that when an element has to be taken out, the
queue will not have to be searched for the element with the highest priority or
we can use an unsorted list so that insertions are always done at the end of
the list.
• Every time when an element has to be removed from the list, the element with
the highest priority will be searched and removed.
• While a sorted list takes O(n) time to insert an element in the list, it takes only
O(1) time to delete an element. On the contrary, an unsorted list will take O(1)
time to insert an element and O(n) time to delete an element from the list.
• Practically, both these techniques are inefficient and usually a blend of these
two approaches is adopted that takes roughly O(log n) time or less.
Linked Representation of a Priority Queue

• In the computer memory, a priority queue can be represented using arrays or


linked lists.
• When a priority queue is implemented using a linked list, then every node of
the list will have three parts: (a) the information or data part, (b) the priority
number of the element, and (c) the address of the next element.
• If we are using a sorted linked list, then the element with the higher priority
will precede the element with the lower priority.
• Consider the priority queue shown in Figure below.

CODING GEEKZ (Dr.S.Priya) 21


Figure: Priority queue
• Lower priority number means higher priority. For example, if there are two
elements A and B, where A has a priority number 1 and B has a priority number
5, then A will be processed before B as it has higher priority than B.

• The priority queue in the above Figure is a sorted priority queue having six
elements. From the queue, we cannot make out whether A was inserted before
E or whether E joined the queue before A because the list is not sorted based
on FCFS. Here, the element with a higher priority comes before the element
with a lower priority.
Insertion

• When a new element has to be inserted in a priority queue, we have to traverse


the entire list until we find a node that has a priority lower than that of the new
element. The new node is inserted before the node with the lower priority.

• However, if there exists an element that has the same priority as the new
element, the new element is inserted after that element. For example, consider
the priority queue shown in Figure below.

Figure: Priority queue


• However, we can definitely say that C was inserted in the queue before D
because when two elements have the same priority the elements are arranged
and processed on FCFS principle.
• If we have to insert a new element with data = F and priority number = 4, then
the element will be inserted before D that has priority number 5, which is lower
priority than that of the new element. So, the priority queue now becomes as
shown in Figure below.

Figure 8.27 Priority queue after insertion of a new node

• However, if we have a new element with data = F and priority number = 2, then
the element will be inserted after B, as both these elements have the same
priority but the insertions are done on FCFS basis as shown in Figure below.

Figure : Priority queue after insertion of a new node

CODING GEEKZ (Dr.S.Priya) 22


Deletion

• Deletion is a very simple process in this case. The first node of the list will be
deleted and the data of that node will be processed first

APPLICATIONS – SCHEDULING
• When a resource is shared among multiple consumers. Examples include CPU
scheduling, Disk Scheduling.
• When data is transferred asynchronously (data not necessarily received at the
same rate as sent) between two processes. Examples include IO Buffers, pipes,
etc.

CODING GEEKZ (Dr.S.Priya) 23

You might also like