Queue
Queue
Queue
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
end procedure
isempty()
Algorithm of isempty() function −
Algorithm
begin procedure isempty
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
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.
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
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.
First we check if the queue is full. If its not full we insert an element
at front end by following the given conditions :
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.
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.
Removing Highest
Priority Element
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.
Peek operation returns the maximum element from Max Heap or minimum
element from Min Heap without deleting the node.
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.
Dijkstra's algorithm
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.
Check if deque is
empty
1 and rear = -1 .
4. Else if front is at the end (i.e. front = n - 1 ), set go to the front front =
0.
Check if deque is
empty
Time Complexity
The time complexity of all the above operations is constant i.e. O(1) .
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: