You are on page 1of 33

Queue

A Queue is a non-primitive linear data structure.


A Queue is a linear list in which elements can be inserted only at one end
called the rear of the queue and deleted only at the other end called the
front of the queue.

Car lined in Toll Gate. Luggage kept on conveyor belts in the Airport.

People standing in a long line to get cinema tickets.

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


In a queue, the insertion operation is known as enqueue and deletion is
known as dequeue.

Front Rear Front Rear Front Rear

A B C D E A B C D E F B C D E F
Insert an element Delete an element
Initial Queue
(ENQUEUE) (DEQUEUE)

Queue is also called First-IN-FIRST-OUT (FIFO) type of data structure.

Queue can be represented either by using an array or by using a linked list.

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Queue implementation using an array:
#define MAX 10;
int queue_arr[MAX];
int rear = -1;
int front = -1;

(a) Empty queue (b) enqueue 5 (c) enqueue 10


front =-1 rear=-1 front =0 rear=0 front =0 rear=1
5 5 10
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]

(d) enqueue 15 5 (e) dequeue 10 (f) dequeue


front =0 rear=2 front =1 rear=2 front =2 rear=2
5 10 15 10 15 15
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]

(g) dequeue 15 (h) enqueue 20 (i) enqueue 25


front =3 rear=2 front =3 rear=3 front =3 rear=4
20 20 25
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Initially when the queue is empty, the values of both front and rear will be
-1.
For Insertion, the value of rear is incremented by 1 and the element is
inserted at the new rear position.

For Deletion, the element at front position is deleted and the value of front
is incremented by 1.

When insertion is done in an initially empty queue, i.e. if the value of front
is -1, then value of front is made 0.

Queue is empty:
front = = -1 || front = = rear+1

Queue is full:
rear = = MAX-1

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Basic Operations on Queue
In order to make manipulations in a stack, there are certain operations
provided to us.

➢ Enqueue( ) to insert an element into the queue

➢ Dequeue( ) to remove an element from the queue

➢ peek( ) To display the element at the front

➢ isEmpty( ) returns true if queue is empty else false.

➢ isFull( ) returns true if queue is full else false.

➢ display( ) to print all elements of the queue.

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Enqueue operation: Enqueue( ) adds an item to the queue from the rear side. If
the queue is full, then it is said to be an Overflow condition i.e. rear = = MAX-1.

void Enqueue(int item)


{
if(rear == MAX-1){
print("Overflow"); //queue is full.
return;
}
if(front == -1){ //If the queue is empty
front = 0;
rear = 0;
queue_arr[rear] = item;
}
else{
rear = rear + 1; //rear point to the next index
queue_arr[rear] = item;
}
}
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Dequeue operation: Dequeue( ) delete an item to the queue from the front side.
If the queue is already empty, in that case, we return an underflow error. If the
queue is not empty, we delete the front node and move the front pointer to the
next node.
int dequeue()
{
int temp;
if(front = = -1) //If the queue is empty
{
printf("Underflow");
return 0;
}
if(front = = rear) //If queue has only one element
{
temp = queue_arr[front];
front = -1;
rear = -1;
return temp;
}
else
{
temp = queue_arr[front];
front = front + 1;
return temp;
}
} Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Peek Operation: This operation returns the value of the data element at the
front of the queue without deleting it.
int peek( )
{
if(isEmpty())
{
printf(“stack underflow”);
return;
}
return queue_arr(front);
}

isEmpty( ) Operation isFull( ) Operation

int isEmpty( ) int isFull( )


{ {
if(front == -1 || front == rear+1) if(rear == MAX-1)
return 1; return 1;
else else
return 0; return 0;
} }
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
display( ): print all elements of the queue.

void display( )
{
int i;
if(isEmpty())
{
printf(“queue is empty\n”);
return;
}
printf(“Queue elements are: ”);
for(i=front; i<=rear; i++)
printf(“%d\n”, queue_arr(i));
printf(“\n”);
}

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Applications of Linear Queue
The major applications of the queue data structure are:

1. Asynchronous data transfer


We can make use of queues to transfer data asynchronously. Asynchronous transfer means when
the rate of transmission of data is not the same between two processes. For example, queues are
used in pipes, file input/output, sockets for asynchronous data transfer.

2. Multiple users for a single resource


Whenever we need to make the process wait for a single shared resource, we maintain them
inside a queue. For example, printer, CPU, etc are the shared resources.

3. Used as buffers
Queues are useful as a buffer to store the data primarily whenever required. For example, the
queue is used as a buffer in the case of MP3 players. CD players, etc.

4. Interrupt handling
Whenever a process gets interrupted, it is sent back and made to wait in the queue. Thus, queue
helps in interrupt handling.

5. Maintain playlists
Queues help maintain any kinds of lists. We can maintain a playlist of songs or other media with
the help of queues.
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Disadvantages of array implementation

• It is not dynamic i.e., it doesn’t grow and shrink depending on needs at


runtime.

• The total size of the queue must be defined beforehand.

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Queue implementation using a Linked List:
• When the size of the queue is not known in advance, it is better to
implement it as a linked list.

• The main advantage of using a linked list over arrays is that it is possible to
implement a queue that can shrink or grow as much as needed.

struct node
{
int info;
struct node *link;
};
struct node *front = NULL;
struct node *rear = NULL;

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


(a) Empty Queue Enqueue(5) Enqueue(10)
front= -1 rear= -1 front rear front rear

5 5 10

Enqueue(15) Dequeue
front rear front rear

5 10 15 10 15

Enqueue(20) Dequeue
front rear front rear

10 15 20 15 20

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India

Enqueue operation: Enqueue( ) insert an item to the queue at the end of the
linked list.
void enqueue(int item)
{
struct node *tmp;
tmp = (struct node*)malloc(sizeof(struct node));
if(tmp = = NULL) /*Memory is full*/
{
printf(“memory not available\n”);
return;
}
tmp -> info = item;
tmp->link = NULL;
if(front = = NULL)
front = tmp;
else
rear->link = tmp;
rear = tmp;
}
Enqueue(5) Enqueue(10)
front rear front rear

5 5 10
Dequeue operation: Dequeue( ) delete an item to the queue from the front side.
If the queue is already empty, in that case, we return an underflow error. If the
queue is not empty, we delete the front node and move the front pointer to the
next node.

int Dequeue( )
{ front rear
struct node * tmp;
int item;
10 15 20
if(isEmpty())
{
printf(“Queue underflow”); Dequeue
return; front rear
}
tmp = front; 15 20
item = tmp->info;
front = front->1ink;
free(tmp);
return item;
}

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Peek Operation:
int peek( )
{
if(isEmpty())
{
printf(“Queue underflow”);
return;
}
return front->info;
}

isEmpty( ) Operation int isEmpty( )


{
if(front == NULL)
return 1;
else
return 0;
}

isFull( ) Operation: This operation is not required.


Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
display( ): print all elements of the queue.
void display( )
{
struct node *ptr;
ptr = front;
if(isEmpty())
{
printf(“Queue is empty\n”);
return;
}
printf(“Queue elements: ”);
while(ptr!=NULL)
{
printf(“%d\n”, ptr->info);
ptr = ptr->link;
}
}

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Circular Queue
As we have seen that when queue is implemented as an array, insertion is
not possible after rear reaches the last position of array. There may be vacant
positions in the array but they can’t be utilized.
To overcome this limitation we use the concept of circular queue.
[0]
(a) enqueue 30
front =3 rear=4 [1]
20 25
[0] [1] [2] [3] [4]
25
[4]

[0]
20 [2]
30 [1]
[3]
Note: After the (n-1)th position, 0th position
occurs. We can be inserted at 0th position. 25
[4]
(a) enqueue 30
front =3 rear=0
20 [2]
30 20 25
[0] [1] [2] [3] [4] [3]
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Insertion and deletion operations in a circular queue can be performed in a
manner similar to that of queue but we have to take care of two things.

If value of rear is MAX-1, then instead of incrementing rear we will


make it zero and then perform insertion.

Similarly, when the value of front becomes MAX-1, it will not be


incremented but will be reset to zero.

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


(a) Empty queue (b) enqueue 5 (c) enqueue 10
front =-1 rear=-1 front =0 rear=0 front =0 rear=1
5 5 10
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]

(d) dequeue (e) dequeue (imp) (f) enqueue 15, 20, 25


front =1 rear=1 front =2 rear=1 front =2 rear=2
10 15 20 25
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]

(g) enqueue 30 (h) dequeue (i) enqueue 35


front =2 rear=0 front =3 rear=0 front =3 rear=1
30 15 20 25 30 20 25 30 35 20 25
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]
(j) enqueue 40 (k) dequeue (l) dequeue
front =3 rear=2 front =2 rear=1 front =0 rear=2
30 35 40 20 25 30 35 40 25 30 35 40
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]

(m) enqueue 45 (n) Enqueue 50 (O) dequeue


front =0 rear=3 front =0 rear=4 front =1 rear=4
30 35 40 45 30 35 40 45 50 35 40 45 50
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Circular Queue will be empty in three situations:
1. Initially, front == -1 (Case a)
2. front == rear+1 (Case e)
3. front == 0 && rear ==MAX-1 (Case O, when all elements are deleted)

Circular Queue will be full in two situations:


1. front == 0 && rear = = MAX-1 (Case n)
2. front == rear + 1 (Case j)

We should make some changes in our procedure so that we can differentiate


between an empty queue and a full queue.

When the only element of the queue is deleted, front and rear are reset
to -1. We can check for empty queue just by checking the value of front,
if
front == -1 then queue is empty.

(a) Initial queue (b) dequeue (imp) (c) Insert 50


front =3 rear=3 front =-1 rear=-1 front =0 rear=0
45 50
[0] [1] [2] [3] [4] [0] [1] [2] [3] [4] [0] [1] [2] [3] [4]

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Enqueue operation: Enqueue( ) adds an item to the queue from the rear side.

void Enqueue(int item)


{
if(isFULL())
{
print(“Queue Overflow"); //queue is full.
return;
}
if(front == -1){ //If the queue is empty
front = 0;

if(rear == MAX-1) //rear is at last position of queue


rear = 0;
else
rear = rear + 1; //rear point to the next index
cqueue_arr[rear] = item;

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


Dequeue operation: Dequeue( ) delete an item to the queue from the front side.

int dequeue()
{
int item;
if(isEmpty()) //If the queue is empty
{
printf(“Queue Underflow");
return 0;
}
item = cqueue_arr[front];
if(front = = rear) //If queue has only one element
{
front = -1;
rear = -1;
}
else if(front == MAX-1)
front = 0;
else
front = front + 1;
return item;

}
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Peek Operation: This operation returns the value of the data element at the
front of the queue without deleting it.
int peek( )
{
if(isEmpty())
{
printf(“Queue underflow”);
return;
}
return cqueue_arr[front];
}

isEmpty( ) Operation
int isEmpty( )
{
if(front == -1)
return 1;
else
return 0;

} Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


isFull( ) Operation

int isFull( )
{
if(front == 0 && rear == MAX-1)|| (front == rear+1))
return 1;
else
return 0;
}

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


display( ): print all elements of the circular queue.
void display( )
{
int i;
if(isEmpty())
{
printf(“queue is empty\n”);
return;
}
printf(“Queue elements are: ”);
i = front;
if (front < = rear)
{
while(i<=rear)
printf(“%d\n”, cqueue_arr[i++]);
}
else
{
while(i<=MAX-1)
printf(“%d\n”, cqueue_arr[i++]);
i=0;
while(i<=rear)
printf(“%d\n”, cqueue_arr[i++]);
}
}
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Deque

Deque is a linear list in which elements can be inserted and deleted at either
end of the list but not in the middle. The term deque is a short form of double
ended queue.

Deque can be used to implement the functionalities of both Stack (LIFO


approach i.e., Last In First Out) and Queue (FIFO approach i.e., First In
First Out).

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


We will implement the deque using a circular array.

The following operations can be performed on deque are:


1. Insertion at the front end (addFirst)
2. Insertion at the rear end (addLast)
3. Deletion at the front end (removeFirst )
4. Deletion at the rear end (removeLast)

Deque can be of two types:


1. Input restricted deque
2. Output restricted deque

1. Input restricted deque: Elements can be inserted at only one end but
deletion can be performed from both ends.
2. Output restricted deque: Elements can be inserted from both ends but
deletion can be performed at only one end.
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Priority Queue

A priority queue is a collection of elements such that each


element has been assigned a priority and the order in which
elements are deleted and processed comes from the following
rules:
• An element of higher priority is processed before any
element of lower priority
• Two elements with the same priority are processed
according to the FIFO rule i.e. order in which they were
added to the queue.

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


There are two types of Priority Queues. They are:

1. Ascending Priority Queue (Min-priority Queue): Element can be


inserted arbitrarily but only smallest element can be removed. For example,
suppose there is an array having elements 4, 2, 8 in the same order. So, while
inserting the elements, the insertion will be in the same sequence but while
deleting, the order will be 2, 4, 8.

2. Descending priority Queue (Max-priority Queue): Element can be


inserted arbitrarily but only the largest element can be removed first from the
given Queue. For example, suppose there is an array having elements 4, 2, 8
in the same order. So, while inserting the elements, the insertion will be in the
same sequence but while deleting, the order will be 8, 4, 2.

Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India


There are two ways of implementing a priority queue:

Through queue: In this case, insertion is simple because the


element is simply added at the rear end as usual. For
performing the deletion, first the element with the highest
priority is searched and then deleted.

Through sorted list: In this case, insertion is costly because


the element is inserted at the proper place in the list based on
the priority. Here deletion is easy since the element with the
highest priority will always be in the beginning of the list.
(advisable to use linked list)
struct node
{
int priority;
int info;
struct node *link;
};
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Enqueue ( )
void priority_enqueue(int item, int item_priority)
{
struct node *tmp, *p;
tmp = (struct node*)malloc(sizeof(struct node));
if(tmp = = NULL) /*Memory is full*/
{
printf(“memory not available\n”);
return;
}
tmp -> info = item;
tmp -> priority = item_priority;
/* Queue is empty or item to be added has priority more than first element*/
tmp->link = NULL;
if(isEmpty() || item_priority < front->priority)
{
tmp->link = front;
front = tmp;
}
else
{
p = front;
while(p->link!=NULL && p->link->priority <= item_priority)
p = p->link;
tmp->link = p->link;
p->link = tmp;
}
} Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India
Dequeue( )
int priority_dequeue( )
{
struct node * tmp;
int item;
if(isEmpty())
{
printf(“Queue underflow”);
return;
}
tmp = front;
item = tmp->info;
front = front->1ink;
free(tmp);
return item;
}

isEmpty( ) Operation int isEmpty( )


{
if(front == NULL)
return 1;
else
return 0;
}
Prepared by: Dr Deepak Gupta, CSED, MNNIT Allahabad, India

You might also like