Module 3.3 Queues
Module 3.3 Queues
1
• People moving on an escalator. The people who got on the escalator first
will be the first one to step out of it.
• People waiting for a bus. The first person standing in the line will be the first
one to get into the bus.
• People standing outside the ticketing window of a cinema hall. The first
person in the line will get the ticket first and thus will be the first one to move
out of it.
• Luggage kept on conveyor belts. The bag which was placed first will be the
first to come out at the other end.
• Cars lined at a toll bridge. The first car
to reach the bridge will be the first to
leave.
• In all these examples, we see that the
element at the first position is served
first. Same is the case with queue data 2
structure (FIFO).
QUEUES
• 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.
3
Queue operations
1. enqueue() − add (insert) an item to the rear of queue.
2. dequeue() − remove (delete) an item from the front of the queue.
4
ARRAY REPRESENTATION OF QUEUES
Insert Operation/enqueue()
• The insert operation is used to insert an element into the rear of queue.
• To add an element into the queue, REAR would be incremented by 1 and
the value would be stored at the position pointed by REAR.
• However, before inserting an element in a queue, 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.
5
• In Step 1, first check for the overflow condition.
• In Step 2, we check if the queue is empty (rear=-1 and front
=-1). 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.
6
Delete Operation/ dequeue()
• The delete operation is used to delete the front most element from a queue.
• If we want to delete an element from the queue, then the value of FRONT will
be incremented by 1.
• Deletions are done from only this end of the queue.
• However, before deleting an element from a queue, we must check for
underflow conditions.
• An underflow condition occurs when we try to delete an element from a queue
that is already empty.
• If FRONT = –1 and FRONT > REAR it means there is no element in the
queue.
7
• 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.
8
#include<stdio.h> switch(choice)
#include<stdlib.h> {
int MAX, queue[10], front=-1, rear=-1; case 1: printf("Enter value to push ");
void enqueue(int); scanf("%d",&num);
void dequeue(); enqueue(num);
int peek(void); break;
void display(int); case 2: dequeue();
int main() break;
{ case 3: val = peek();
int choice, num; if (val != -1)
printf("\n Enter the size of QUEUE: "); printf(“\n The first value in queue is : %d”,
val);
scanf("%d",&MAX);
break;
while(1)
case 4: display();
{
break;
printf("\n1.INSERT\n 2.DELETE \n3. PEEK
case 5: printf("\n EXIT POINT\n");
4.DISPLAY \n5.E XIT“);
exit(0);
printf("\n Enter the Choice: ");
default: printf ("\nEnter Valid Choice\n");
scanf("%d",&choice);
} } 9
return 0; }
void enqueue (int num) void dequeue( )
{ {
if(rear == MAX-1) if(front == -1 || front>rear)
{ {
printf(“\n OVERFLOW”); printf(“\n UNDERFLOW”);
return return;
} }
else if(front == -1 && rear == - else
1) {
{ val = queue[front];
front = rear = 0; printf(“Deleted Item %d”, val);
} front++;
else if(front > rear)
{ {
rear++; front = rear = -1;
} }
10
queue[rear] = num; }}
void display( )
int peek() {
{ int i;
if(front==-1 || front>rear) if(front == -1 || front > rear)
{ {
printf(“\n QUEUE IS EMPTY”); printf(“\n QUEUE EMPTY”);
return -1; }
} else
else {
{ printf(“Queue dat \n”);
return queue[front]; for(i = front; i <= rear; i++)
} {
} printf(“\t %d”, queue[i]);
}
}
}
11
Drawback of array representation of Queue
• Its drawback is that the array must be declared to have some fixed size.
• If we allocate space for 50 elements in the queue and it hardly uses 20–25
locations, then half of the space will be wasted.
• And in case we allocate less memory locations for a queue that might end up
growing large and large, then a lot of re-allocations will have to be done,
thereby creating a lot of overhead and consuming a lot of time.
• In case the queue is a very small one or its maximum size is known in
advance, then the array implementation of the queue gives an efficient
implementation.
• But if the array size cannot be determined in advance, the other alternative,
i.e., the linked representation is used. 12
LINKED REPRESENTATION OF QUEUES
• In a linked queue, 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 FRONT.
• Here, will 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.
13
Insert Operation
• To insert an element, we first check if FRONT=NULL. If the condition holds, then the queue is
empty. Then 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.
• 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, 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.
• 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.
14
Delete Operation
• 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.
• Before deleting the value, we must first check if FRONT=NULL the queue is empty and no more
deletions can be done (underflow).
• 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.
19
• Look at the queue shown in above Figure. If you want to insert another value, it will
not be possible because the queue is completely full. There is no empty space where
the value can be inserted.
• Consider a scenario in which two successive deletions are made. The queue will then
be given as shown in below Figure.
• Suppose we want to insert a new element. 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.
20
• To resolve this problem, we have two solutions.
• 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.
• The second option is to use a circular queue.
21
Circular Queue
• In the circular queue, the first index comes after the last index.
• The circular queue will be full only when front = 0 and rear = Max – 1
• A circular queue is implemented in the same manner as a linear queue
• The only difference is in the code that performs insertion and deletion
operations.
22
Circular Queue - Insertion
For insertion, three conditions are checked:
1. If (front = 0 and rear = MAX – 1) or
REAR=FRONT-1 then the circular
queue is full.
2. check if the queue is empty (rear=-1
and front =-1). then both FRONT
and REAR are set to zero
3. If rear != MAX – 1, then rear will be
incremented and the value will
be inserted
4. If front != 0 and rear = MAX – 1,
then queue is not full. 23
Circular Queue - Deletion
• If front = –1, then there are no elements
in the queue. So, an underflow condition
will be reported.
25
printf("\n 3. Display ");
Circular Queue using Arrays printf("\n 4. EXIT\n");
#include <stdio.h> scanf("%d", &choice);
#include <stdlib.h> switch(choice)
#define MAX 5 {
int queue[MAX]; case 1: printf("\n Enter Insert value: ");
int front= -1, rear= -1;
scanf("%d", &num);
void insert(int);
insert(num);
void delete_element(void);
void display(void); break;
case 2: delete_element();
int main() break;
{ case 3: display();
int choice, num; break;
while(1)
case 4: exit(0);
{
}
printf("\n Enter choice : ");
printf("\n 1. Insert "); }
26
printf("\n 2. Delete"); return 0; }
void insert(int num) void delete_element()
{ {
if((front==0 && rear==MAX-1)|| REAR=FRONT-1) if(front==-1 && rear==-1) //Empty Queue
{ {
printf("\n OVERFLOW"); printf("\n QUEUE IS EMPTY");
} return;
else if(front==-1 && rear==-1) //Empty Queue }
{ printf("Deleted item: %d\n",queue[front]);
front=rear=0; if(front==rear) //Single element
queue[rear]=num; {
} front=rear=-1;
else if(rear==MAX-1 && front!=0) }
{ else if(front==MAX-1)
rear=0; {
queue[rear]=num; front=0;
} }
else else
{ {
rear++; front++;
queue[rear]=num; }
} return;
27
} }
void display()
{
int i;
if (front == -1 && rear == -1)
printf ("\n QUEUE IS EMPTY");
else
{
if(front<rear)
{
for(i=front;i<=rear;i++)
printf("\t %d", queue[i]);
}
else
{
for(i=front;i<MAX;i++)
printf("\t %d", queue[i]);
for(i=0;i<=rear;i++)
printf("\t %d", queue[i]);
}
}
} 28
while(1)
return ;
} 30
Deleting a Node from front in a Circular Queue
void deletefront() else
{ { // more than 1 nodes
NODE *temp; ptr = front;
if((front == NULL) &&(rear == NULL)) front = front->next; // Make the
second node as front
{
node
printf(“ Queue Empty\n”); rear->next = front; // Link last node
} to the new front
else if(front->next == front) // only one node node
{ printf(“Item deleted: %d\n",ptr->num);
printf(“Item deleted: %d\n",front->num); free(ptr);
free(front); }
front = rear = NULL; return ;
} }
31
void display( )
{
NODE *ptr;
ptr = front;
Display Circular Queue
if (ptr == NULL)
printf("Queue empty\n");
else
{
printf("The Queue data are \n");
do
{
printf("%d\n", ptr ->num);
ptr = ptr ->next;
}
while(ptr != front);
}
return;
} 32
Priority Queues
• 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
• An element with higher priority is processed before an element with a lower priority.
• Two elements with the same priority are processed on a first-come-first-served (FCFS)
basis.
• A priority queue can be thought of as a modified queue in which when an
element has to be removed from the queue, the one with the highest-priority is
retrieved first.
• The priority of the element can be set based on various factors.
• Priority queues are widely used in operating systems to execute the highest
33
priority process first.
Implementation of Priority Queue
There are two ways to implement a priority queue.
1. Use a sorted list to store the elements, and when an element has to be
taken out, the queue need not be searched for the element with the highest
priority
2. 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
34
Linked Representation of a Priority Queue
• When a priority queue is implemented using a linked list, then every node of
the list will have three parts:
(a) the data part,
(b) the priority number of the element,
(c) the address of the next element.
• If a sorted linked list is used, then the element with the higher priority will
precede the element with the lower priority.
• Ie., Lower priority number means higher priority
• when two elements have the same priority the elements are arranged and
processed on FCFS principle. 35
Insertion
36
• 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.
• 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
37
Deletion
• Deletion is a very simple and direct. The first node of the list is deleted
and the data of that node will be processed first.
38