Unit-3 21CSC201J
Unit-3 21CSC201J
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
Figure : Stack
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.
• 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.
• 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
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 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
• 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.
Algorithm:
• 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
• 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
Algorithm:
Algorithm:
Example:
• 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)
• 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.
• 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.
• 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.
• 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.
• 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.
• 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
• 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:
• 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.
• Consider a scenario in which two successive deletions are made. The queue will then
be given as shown in the below figure.
• 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.
• 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.
ALGORITHM - INSERTION
• 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.
• 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.
ALGORITHM – DELETION
• 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
• 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
• 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.
• 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.
• 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.