You are on page 1of 23

Queue is an abstract data structure, somewhat similar to Stacks.

Unlike stacks, a queue is


open at both its ends. One end is always used to insert data (enqueue) and the other is used to
remove data (dequeue). Queue follows First-In-First-Out methodology, i.e., the data item
stored first will be accessed first.

A real-world example of queue can be a single-lane one-way road, where the vehicle enters
first, exits first. More real-world examples can be seen as queues at the ticket windows and
bus-stops.

Queue Representation
As we now understand that in queue, we access both ends for different reasons. The
following diagram given below tries to explain queue representation as data structure −

As in stacks, a queue can also be implemented using Arrays, Linked-lists, Pointers and
Structures. For the sake of simplicity, we shall implement queues using one-dimensional
array.

Basic Operations
Queue operations may involve initializing or defining the queue, utilizing it, and then
completely erasing it from the memory. Here we shall try to understand the basic operations
associated with queues −
 enqueue() − add (store) an item to the queue.
 dequeue() − remove (access) an item from the queue.
Few more functions are required to make the above-mentioned queue operation efficient.
These are −
 peek() − Gets the element at the front of the queue without removing it.
 isfull() − Checks if the queue is full.
 isempty() − Checks if the queue is empty.
In queue, we always dequeue (or access) data, pointed by front pointer and while enqueing
(or storing) data in the queue we take help of rear pointer.
peek()
This function helps to see the data at the front of the queue. The algorithm of peek() function
is as follows −
Algorithm
begin procedure peek
return queue[front]
end procedure

isfull()
As we are using single dimension array to implement queue, we just check for the rear
pointer to reach at MAXSIZE to determine that the queue is full. In case we maintain the
queue in a circular linked-list, the algorithm will differ. Algorithm of isfull() function −
Algorithm
begin procedure isfull

if rear equals to MAXSIZE


return true
else
return false
endif

end procedure

isempty()
Algorithm of isempty() function −
Algorithm
begin procedure isempty

if front is less than MIN OR front is greater than rear


return true
else
return false
endif

end procedure

Enqueue Operation
Queues maintain two data pointers, front and rear. Therefore, its operations are
comparatively difficult to implement than that of stacks.
The following steps should be taken to enqueue (insert) data into a queue −
 Step 1 − Check if the queue is full.
 Step 2 − If the queue is full, produce overflow error and exit.
 Step 3 − If the queue is not full, increment rear pointer to point the next empty
space.
 Step 4 − Add data element to the queue location, where the rear is pointing.
 Step 5 − return success.
Algorithm for enqueue operation
procedure enqueue(data)

if queue is full
return overflow
endif

rear ← rear + 1
queue[rear] ← data
return true

end procedure

Dequeue Operation
Accessing data from the queue is a process of two tasks − access the data where front is
pointing and remove the data after access. The following steps are taken to
perform dequeue operation −
 Step 1 − Check if the queue is empty.
 Step 2 − If the queue is empty, produce underflow error and exit.
 Step 3 − If the queue is not empty, access the data where front is pointing.
 Step 4 − Increment front pointer to point to the next available data element.
 Step 5 − Return success.
Algorithm for dequeue operation
procedure dequeue

if queue is empty
return underflow
end if

data = queue[front]
front ← front + 1
return true

end procedure

Array representation of Queue


We can easily represent queue by using linear arrays. There are two variables i.e.
front and rear, that are implemented in the case of every queue. Front and rear
variables point to the position from where insertions and deletions are performed in
a queue. Initially, the value of front and queue is -1 which represents an empty
queue. Array representation of a queue containing 5 elements along with the
respective values of front and rear, is shown in the following figure.

The above figure shows the queue of characters forming the English word "HELLO".
Since, No deletion is performed in the queue till now, therefore the value of front
remains -1 . However, the value of rear increases by one every time an insertion is
performed in the queue. After inserting an element into the queue shown in the
above figure, the queue will look something like following. The value of rear will
become 5 while the value of front remains same.
After deleting an element, the value of front will increase from -1 to 0. however, the
queue will look something like following.

Algorithm to insert any element in a queue


Check if the queue is already full by comparing rear to max - 1. if so, then return an
overflow error.

If the item is to be inserted as the first element in the list, in that case set the value of
front and rear to 0 and insert the element at the rear end.
Otherwise keep increasing the value of rear and insert each element one by one
having rear as the index.

Algorithm

o Step 1: IF REAR = MAX - 1


Write OVERFLOW
Go to step
[END OF IF]
o Step 2: IF FRONT = -1 and REAR = -1
SET FRONT = REAR = 0
ELSE
SET REAR = REAR + 1
[END OF IF]
o Step 3: Set QUEUE[REAR] = NUM
o Step 4: EXIT

Circular Queue
There was one limitation in the array implementation of Queue. If the rear reaches to
the end position of the Queue then there might be possibility that some vacant
spaces are left in the beginning which cannot be utilized. So, to overcome such
limitations, the concept of the circular queue was introduced.
As we can see in the above image, the rear is at the last position of the Queue and
front is pointing somewhere rather than the 0 th position. In the above array, there are
only two elements and other three positions are empty. The rear is at the last
position of the Queue; if we try to insert the element then it will show that there are
no empty spaces in the Queue. There is one solution to avoid such wastage of
memory space by shifting both the elements at the left and adjust the front and rear
end accordingly. It is not a practically good approach because shifting all the
elements will consume lots of time. The efficient approach to avoid the wastage of
the memory is to use the circular queue data structure.

What is a Circular Queue?


A circular queue is similar to a linear queue as it is also based on the FIFO (First In
First Out) principle except that the last position is connected to the first position in a
circular queue that forms a circle. It is also known as a Ring Buffer.

Operations on Circular Queue


The following are the operations that can be performed on a circular queue:
o Front: It is used to get the front element from the Queue.
o Rear: It is used to get the rear element from the Queue.
o enQueue(value): This function is used to insert the new value in the Queue. The new
element is always inserted from the rear end.
o deQueue(): This function deletes an element from the Queue. The deletion in a
Queue always takes place from the front end.

Applications of Circular Queue


The circular Queue can be used in the following scenarios:

o Memory management: The circular queue provides memory management. As we


have already seen that in linear queue, the memory is not managed very efficiently.
But in case of a circular queue, the memory is managed efficiently by placing the
elements in a location which is unused.
o CPU Scheduling: The operating system also uses the circular queue to insert the
processes and then execute them.
o Traffic system: In a computer-control traffic system, traffic light is one of the best
examples of the circular queue. Each light of traffic light gets ON one by one after
every interval of time. Like red light gets ON for one minute then yellow light for one
minute and then green light. After green light, the red light gets ON.

Double Ended Queue


Double ended queue is a more generalized form of queue data
structure which allows insertion and removal of elements from both
the ends, i.e , front and back.
Implementation of Double ended Queue

Here we will implement a double ended queue using a circular


array. It will have the following methods:

 push_back : inserts element at back

 push_front : inserts element at front

 pop_back : removes last element

 pop_front : removes first element

 get_back : returns last element

 get_front : returns first element

 empty : returns true if queue is empty

 full : returns true if queue is full

Insert Elements at Front

First we check if the queue is full. If its not full we insert an element
at front end by following the given conditions :

 If the queue is empty then intialize front and rear to 0. Both


will point to the first element.

 Else we decrement front and insert the element. Since we are


using circular array, we have to keep in mind that if front is
equal to 0 then instead of decreasing it by 1 we make it equal
to SIZE-1.

Insert Elements at back

Again we check if the queue is full. If its not full we insert an


element at back by following the given conditions:

 If the queue is empty then intialize front and rear to 0. Both


will point to the first element.

 Else we increment rear and insert the element. Since we are


using circular array, we have to keep in mind that if rear is
equal to SIZE-1 then instead of increasing it by 1 we make it
equal to 0.
Delete First Element

In order to do this, we first check if the queue is empty. If its not


then delete the front element by following the given conditions :

 If only one element is present we once again make front and


rear equal to -1.

 Else we increment front. But we have to keep in mind that if


front is equal to SIZE-1 then instead of increasing it by 1 we
make it equal to 0.

Priority Queue
A priority queue is a special type of queue in which each element is
associated with a priority value. And, elements are served on the basis of
their priority. That is, higher priority elements are served first.
However, if elements with the same priority occur, they are served
according to their order in the queue.

Assigning Priority Value


Generally, the value of the element itself is considered for assigning the
priority. For example,

The element with the highest value is considered the highest priority
element. However, in other cases, we can assume the element with the
lowest value as the highest priority element.

We can also set priorities according to our needs.

Removing Highest
Priority Element

Difference between Priority Queue and Normal Queue

In a queue, the first-in-first-out rule is implemented whereas, in a priority


queue, the values are removed on the basis of priority. The element with
the highest priority is removed first.
Implementation of Priority Queue
Priority queue can be implemented using an array, a linked list, a heap data
structure, or a binary search tree. Among these data structures, heap data
structure provides an efficient implementation of priority queues.

Hence, we will be using the heap data structure to implement the priority
queue in this tutorial. A max-heap is implemented in the following
operations. If you want to learn more about it, please visit max-heap and
min-heap.
A comparative analysis of different implementations of priority queue is
given below.

Operations peek insert delete

Linked List O(1) O(n) O(1)

Binary Heap O(1) O(log n) O(log n)

Binary Search Tree O(1) O(log n) O(log n)

Priority Queue Operations


Basic operations of a priority queue are inserting, removing, and peeking
elements.
1. Inserting an Element into the Priority Queue

Inserting an element into a priority queue (max-heap) is done by the


following steps.

 Insert the new element at the end of the tree.

 Insert an element at the end of the queue

 Heapify the tree.


 Heapify after insertion
2. Deleting an Element from the Priority Queue

Deleting an element from a priority queue (max-heap) is done as follows:


 Select the element to be deleted.
Select the element to be deleted

 Swap it with the last element.


Swap with the last leaf node element

 Remove the last element.


Remove the last element leaf
 Heapify the tree.

3. Peeking from the Priority Queue (Find max/min)

Peek operation returns the maximum element from Max Heap or minimum
element from Min Heap without deleting the node.

For both Max heap and Min Heap

4. Extract-Max/Min from the Priority Queue

Extract-Max returns the node with maximum value after removing it from a
Max Heap whereas Extract-Min returns the node with minimum value after
removing it from Min Heap.

Priority Queue Applications


Some of the applications of a priority queue are:

 Dijkstra's algorithm

 for implementing stack

 for load balancing and interrupt handling in an operating system

 for data compression in Huffman code


Deque Data Structure
Deque or Double Ended Queue is a type of queue in which insertion and
removal of elements can either be performed from the front or the rear.
Thus, it does not follow FIFO rule (First In First Out).

Representation of Deque

Types of Deque
 Input Restricted Deque
In this deque, input is restricted at a single end but allows deletion at
both the ends.
 Output Restricted Deque
In this deque, output is restricted at a single end but allows insertion
at both the ends.

Operations on a Deque
Below is the circular array implementation of deque. In a circular array, if
the array is full, we start from the beginning.
But in a linear array implementation, if the array is full, no more elements
can be inserted. In each of the operations below, if the array is full,
"overflow message" is thrown.

Before performing the following operations, these steps are followed.

1. Take an array (deque) of size n .


2. Set two pointers at the first position and set front = -1 and rear = 0 .

Initialize an array and pointers for


deque

1. Insert at the Front

This operation adds an element at the front.

1. Check the position of front.

Check the position of


front
2. If front < 1 , reinitialize front = n-1 (last index).

Shift front to the end


3. Else, decrease front by 1.
4. Add the new key 5 into array[front] .

Insert the element at


Front
2. Insert at the Rear

This operation adds an element to the rear.

1. Check if the array is full.

Check if deque is full

2. If the deque is full, reinitialize rear = 0 .


3. Else, increase rear by 1.

Increase the rear


4. Add the new key 5 into array[rear] .

Insert the element at


rear
3. Delete from the Front

The operation deletes an element from the front.

1. Check if the deque is empty.

Check if deque is
empty

2. If the deque is empty (i.e. front = -1 ), deletion cannot be performed


(underflow condition).
3. If the deque has only one element (i.e. front = rear ), set front = -

1 and rear = -1 .
4. Else if front is at the end (i.e. front = n - 1 ), set go to the front front =

0.

5. Else, front = front + 1 .

Increase the front


4. Delete from the Rear

This operation deletes an element from the rear.

1. Check if the deque is empty.

Check if deque is
empty

2. If the deque is empty (i.e. front = -1 ), deletion cannot be performed


(underflow condition).
3. If the deque has only one element (i.e. front = rear ), set front = -

1 and rear = -1 , else follow the steps below.


4. If rear is at the front (i.e. rear = 0 ), set go to the front rear = n - 1 .
5. Else, rear = rear - 1 .

Decrease the rear


5. Check Empty

This operation checks if the deque is empty. If front = -1 , the deque is


empty.
6. Check Full

This operation checks if the deque is full. If front = 0 and rear = n -

1 OR front = rear + 1 , the deque is full.

Time Complexity
The time complexity of all the above operations is constant i.e. O(1) .

Applications of Deque Data Structure


1. In undo operations on software.

2. To store history in browsers.

3. For implementing both stacks and queues.

Application of Queue in Operating System


Queue are widely used in operating systems some of the application of queue in
OS are explained below:

 They can be used for algorithms like First Come First Serve(FCFS).
 It is used as an buffer for input devices like Keyboard.
 It is also used for CPU Scheduling.
 It is widely used for spooling in Printers.
 Queue are also used in Memory Management.
Some other applications of queue data structure:

 Applied as buffers on playing music in the mp3 players or CD players.


 Applied on handling the interruption in the operating system.
 Applied to add a song at the end of the playlist.
 Applied as the waiting queue for using the single shared resources like CPU,
Printers, or Disk.
 Applied to the chat application when someone sends messages to us and we
don’t have an internet connection then the messages are stored in the server
of the chat application.

You might also like