Download as pdf or txt
Download as pdf or txt
You are on page 1of 31

UNIT 1: Data Structures

LESSON 3:
QUEUES

OBJECTIVES:

▪ Elaborate the purpose and mathematical background of


algorithm analysis, particularly queue data structure.

▪ Introduce the idea of Queue Data Structure with real-world


examples.

▪ Discuss the operations that can be used to utilize queues.

▪ Apply all the data structures and algorithm concepts using


several IDE’s, such as, Code Blocks, Dev C++, etc.

▪ Infuse in the minds of the learners that in each problem a single


programmer could develop a unique solution, far different from
the other’s solution, but will arrive on the same result.

▪ Let the students be aware of the different IDE’s that they could
use in developing a program.

IT 201: DATA STRUCTURES AND ALGORITHMS 58


UNIT 1: Data Structures

What is a Queue?
The known description of “queue” is a line, usually of people or things waiting
for something. It implements the idea of “first come, first serve”, in which the first
person or thing coming from that line will be prioritized first before turning to the next,
then afterwards they can get out from the line. This idea is often experienced in
different real-world situations such as waiting in line for a movie, waiting at a check-
out line in the grocery store, or ordering from a fast-food restaurant.

Source: lttps://www.vecteezy.com/vector-art/1237890-people-standing-in-line
Figure 1: Sample image of a waiting line for a movie

In programming concept approach, “Queue” is an abstract data type or linear


data structure, somewhat similar to stacks. But unlike stacks, a queue is open at both
ends. It is considered as an ordered collection of items where the insertion of new
element happens at one end, which is called as the “rear” (also called as the “tail”),
and the removal of existing element takes place from the other end called as the
“front” (also called as the head).

Figure 2: Sample image of a Queue Data Structure

The most recently added item in the queue must wait at the end of the collection.
The item that has been in the collection the longest is at the front. This ordering
principle is sometimes called “FIFO” (first-in first-out), which is also known as the idea
of “first-come first-served” method. Well-behaved lines, or queues, are very restrictive
that they have only one way in and only one way out. There is no jumping in the middle
and no leaving before you have waited the necessary amount of time to get to the
front. Another real-world example of FIFO 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.

IT 201: DATA STRUCTURES AND ALGORITHMS 61


UNIT 1: Data Structures

Just like in stacks, a queue can also be implemented using arrays, linked-lists,
pointers and structures. For the example, we shall implement queues using one-
dimensional array. Initially the head(FRONT) and the tail(REAR) of the queue points
at the first index of the array (starting the index of array from 0). As we add elements
to the queue, the tail keeps on moving ahead, always pointing to the position where
the next element will be inserted, while the head remains at the first index.

The following diagram given below tries to explain queue representation using array.

Figure 3: Sample image of a Queue Data Structure using an array

When we remove an element from Queue, we remove the element from head
position and then move head to the next position. Whenever we move head one
position ahead, after removal of first element, the size on Queue is reduced by one
space each time.

IT 201: DATA STRUCTURES AND ALGORITHMS 62


UNIT 1: Data Structures

Figure 4: After removing an element from the queue

Difference Between Queues and Stacks

In this table, it shows the comparisons between stacks and queues.

Stacks Queues

Uses LIFO (Last in, First out)


Uses FIFO (First in, First out) approach.
approach.

Items are added or deleted from Items are added from “Rear” end of the
only one end called “Top” of the queue and are removed from the “front” of
stack. the queue.

The basic operations for the stack The basic operations for a queue are
are “push” and “Pop”. “enqueue” and “dequeue”.

We can do all operations on the


In queues, we need to maintain two pointers,
stack by maintaining only one
one to access the front of the queue and the
pointer to access the top of the
second one to access the rear of the queue.
stack.

The stack is mostly used to solve Queues are used to solve problems related
recursive problems. to ordered processing.

Basic Operations

To fully utilize or define a queue, there are basic operations that can be used.
These are:

1. enqueue – adds (store) an item to the queue. And;


2. dequeue – removes (access) an item from the queue.

In a queue, we dequeue (or access) the data from the front pointer and
enqueuing (or storing) data in the queue to the rear pointer. There are also few
functions that can be used 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.

IT 201: DATA STRUCTURES AND ALGORITHMS 63


UNIT 1: Data Structures

Let's first learn about supportive functions of a queue –

1. 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
Implementation of peek() function example:
int peek() {
return queue[front];

2. isfull()

Assume that we are using a single dimension array to implement queue, we


just need to check for the rear pointer and compare it to size we set for the array to
determine if the queue is full. Algorithm of isfull() function is as follows −

Algorithm:
begin procedure full
if rear equals to MAXSIZE
return true
else
return false
endif
end procedure

Implementation of isfull() function example:

bool isfull() {
if(rear == MAXSIZE - 1)
return true;
else
return false;
}

3. isempty()

In contrast to isfull() function, the isempty() function determines whether the


queue is empty or not by determining the value that the front holds. Algorithm of
isempty() function is as follows−

IT 201: DATA STRUCTURES AND ALGORITHMS 64


UNIT 1: Data Structures

Algorithm:

begin procedure isempty

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


return true
else
return false
endif

end procedure

If the value of front is less than MIN or 0, it tells that the queue is not yet initialized,
hence empty.

Implementation of isempty() function example:

bool isempty() {
if(front < 0 || front > rear)
return true;
else
return false;
}

Applications of Queue

Let us discuss the various applications of the queue data structure below.

▪ The queue data structure is used in various CPU and disk scheduling. Here
we have multiple tasks requiring CPU or disk at the same time. The CPU or
disk time is scheduled for each task using a queue.
▪ The queue can also be used for print spooling wherein the number of print
jobs is placed in a queue.
▪ Handling of interrupts in real-time systems is done by using a queue data
structure. The interrupts are handled in the order they arrive.
▪ Call center phone systems use queues to hold the calls until they are
answered by the service representatives.

In general, we can say that the queue data structure is used whenever we require
the resources or items to be serviced in First in, First Out order.

IT 201: DATA STRUCTURES AND ALGORITHMS 65


UNIT 1: Data Structures

Enqueue and Dequeue Operation


What is Enqueue and Dequeue?

On the previous chapter, enqueue and dequeue were defined as the


operations used to add and remove an item from a queue. It is the most necessary
operation to utilize the queue data structure. But what are the steps to perform these
operations?

Enqueue Operation

In this process, the following steps are performed:


▪ Check if the queue is full.
▪ If full, produce overflow error and exit.
▪ Else, increment ‘rear’.
▪ Add an element to the location pointed by ‘rear’.
▪ Return success.

Dequeue Operation

Dequeue operation consists of the following steps:


▪ Check if the queue is empty.
▪ If empty, display an underflow error and exit.
▪ Else, the access element is pointed out by ‘front’.
▪ Increment the ‘front’ to point to the next accessible data.
▪ Return success.

Next, we will see a detailed illustration of insertion and deletion operations in queue.

Illustration

This is an empty queue and thus we have rear and empty set to -1.

Figure 5: Shows the structure of an empty queue


Next, we add 1 to the queue and as a result, the rear pointer moves ahead by one
location.

Figure 5.1: Shows the result after adding an element


IT 201: DATA STRUCTURES AND ALGORITHMS 66
UNIT 1: Data Structures

In the next figure, we add element 2 to the queue by moving the rear pointer ahead
by another increment.

Figure 5.2: Shows the result after adding an element

In the following figure, we add element 3 and moved the rear pointer.

Figure 5.3: Shows the result after adding an element

At this point, the rear pointer is at the 2nd location while the front pointer is at the
0th location.
Next, we delete the element pointed by the front pointer. As the front pointer is at 0,
the element that is deleted is 1.

Figure 5.4: Shows the result after deleting an element

Thus, the first element entered in the queue i.e. 1 happens to be the first
element removed from the queue. As a result, after the first dequeue, the front
pointer now will be moved ahead to the next location which is 1.

IT 201: DATA STRUCTURES AND ALGORITHMS 67


UNIT 1: Data Structures

Algorithm for Enqueue and Dequeue Operation


Initialize first the front and rear as an integer, with values 0 and -1 respectively. (front
= 0, rear = -1)

Begin
(See line 27 in the example code)
function Enqueue() to insert elements in queue:
If queue is completely filled up then print “Overflow”.
Otherwise insert element at rear.
Update the value of rear
End
Begin
(See line 44 in the example code)
function Dequeue() to delete elements from queue:
If queue is completely empty then print “Underflow”.
Otherwise insert element from the front.
Update the value of rear.
End

In this example code, it will show how the insertion and deletion of an element in a
queue is applied using C++.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 if(isFull()){
30
31

IT 201: DATA STRUCTURES AND ALGORITHMS 68


UNIT 1: Data Structures

32 }
33 else{
34 if(front==-1)
35 front=0;
36 cout<<"\nEnter an element: ";
37 cin>>ins_item;
38 cout<<"\n";
39 rear=rear+1;
40 arrayq[rear]=ins_item;
41 }
42 }
43
44 void dequeue(){
45 if(isEmpty()){
46 cout<<"\nQueue is empty!\n";
47 return;
48 }
49 else{
50 cout<<"\nElement removed from queue is:
"<<arrayq[front];
51 cout<<"\n";
52 front++;
53 }
54 }
55
56 void display(){
57 int i;
58 if(isEmpty()){
59 cout<<"\nQueue is empty!\n";
60 return;
61 }
62 else{
63 cout<<"\nElements in queue: ";
64 for(i=front; i<=rear; i++)
65 cout<<arrayq[i]<<" "; 66
cout<<"\n";
67 }
68 }
69
70 void peek(){
71 if(isEmpty()){
72 cout<<"\nQueue is empty!\n";
73 return;
74 }
75 else{
76 cout<< "\nFront element is: " << arrayq[front];}
77 cout<<"\n";
78 }
79
80 int main(){
81 int ch;
82 while(1){
83 cout<<"\n[1] Add\n";
84 cout<<"\n[2] Delete\n";
85 cout<<"\n[3] Display\n";
86 cout<<"\n[4] Display Front\n";
87 cout<<"\n[5] Exit\n";
88 cout<<"\nChoice: ";
89 cin>>ch;

IT 201: DATA STRUCTURES AND ALGORITHMS 69


UNIT 1: Data Structures

90
91
92
93
94
95
96
97
98
99
100

The above implementation shows the queue represented as an array. We


specify the maximum size for the array. We also define the enqueue and dequeue
operations as well as the isPeek, isFull and isEmpty operations.

Output:

Figure 6: Shows the enqueueing of an element

Figure 6.1: Shows the elements in the queue

IT 201: DATA STRUCTURES AND ALGORITHMS 70


UNIT 1: Data Structures

Figure 6.2: Shows that the queue is full upon enqueueing an element

Figure 6.3: Shows the front element of the queue

Figure 6.4: Shows the dequeuing of an element

IT 201: DATA STRUCTURES AND ALGORITHMS 71


UNIT 1: Data Structures

Figure 6.5: Shows the updated queue in the array and


the current front element

IT 201: DATA STRUCTURES AND ALGORITHMS 72


UNIT 1: Data Structures

Circular Queues
A circular queue or “ring buffer” is a type of queue in which the last position is
connected to the first position, which is represented by the shape of a circle. It is a
linear data structure in which the operations are performed based on FIFO (First In
First Out) principle of queues.

Figure 7: Shows the structure of a Circular Queue

In a normal Queue, we can insert elements until queue becomes full. But once
queue becomes full, we cannot insert the next element even if there is a space in front
of queue.

Figure 8: Shows the limitation of a regular queue

As you can see in the above image, after a bit of enqueuing and dequeuing, the
size of the queue has been reduced. If you will try to enter an element, it will prompt
that the queue is full although there is still space from the queue. The indexes 0 and
1 can only be used after the queue is reset when all the elements have been
dequeued.

How it works?

Circular Queue works by the process of circular increment. For example, when we try
to increment the pointer and we reach the end of the queue, we start from the
beginning of the queue. With the implementation of Circular Queues, it avoids the
wastage of space in a regular queue implementation using arrays. Circular Queue also
uses the algorithm of enqueue and dequeue.
IT 201: DATA STRUCTURES AND ALGORITHMS 73
UNIT 1: Data Structures

Circular Queue Operations


1. enqueue operation
▪ check if the queue is full
▪ for the first element, set value of front to 0
▪ circularly increase the rear index by 1 (i.e. if the rear reaches the end, next it
would be at the start of the queue)
▪ add the new element in the position pointed to by rear

2. dequeue operation
▪ check if the queue is empty
▪ return the value pointed by front
▪ circularly increase the front index by 1
▪ for the last element, reset the values of front and rear to -1

however, the check for full queue has a new additional case:
▪ case 1: front = 0 && rear == size - 1
▪ case 2: front = rear + 1

the second case happens when rear starts from 0 due to circular increment and when
its value is just 1 less than front, the queue is full.

Figure 9.1: Shows the structure of an empty circular queue

Figure 9.2: Shows the result after adding an element

IT 201: DATA STRUCTURES AND ALGORITHMS 74


UNIT 1: Data Structures

Figure 9.3: Shows the result after adding an element

Figure 9.4: Shows the result of a queue with full elements

Figure 9.5: Shows the result after the deletion of 2 elements

Figure 9.6: Shows the result of a adding an element on 0 th location

IT 201: DATA STRUCTURES AND ALGORITHMS 75


UNIT 1: Data Structures

Figure 9.7: Shows the result of a adding an element on 1 st location

Algorithm for Circular Queues:

1. enqueue()
begin
(See line 27 in the example code)
if front = 0 and rear = n – 1, or front = rear + 1, then queue is full, and return
otherwise
if front = -1, then front = 0 and rear = 0
else
if rear = n – 1, then, rear = 0, else rear := rear + 1
queue[rear] = key
end

2. dequeue(queue)
begin
(See line 53 in the example code)
if front = -1 then queue is empty, and return
otherwise
item := queue[front]
if front = rear, then front and rear will be -1
else
if front = n – 1, then front := 0 else front := front + 1
end

In this example code, it will show how the insertion and deletion of an element in a
circular queue is applied using C++.

10
11
12
IT 201: DATA STRUCTURES AND ALGORITHMS 76
UNIT 1: Data Structures

13 }
14 else
15 return false; 16 }
17
18 bool isEmpty(){
19 if(front==-1){
20 return true; 21
}
22 else
23 return false; 24 }
25
26
27 void enqueue(){
28 int ins_item;
29 if(isFull()){
30 cout<<"\nQueue Overflow!\n";
31 return;
32 }
33 else{
34 cout<<"\nEnter an element: ";
35 cin>>ins_item;
36 cout<<"\n";
37
38 if(front==-1){
39 front = 0;
40 rear = 0;
41 }
42 else {
43 if(rear == MAX - 1)
44 rear = 0;
45 else
46 rear = rear + 1;
47 }
48 arrayq[rear]=ins_item;
49 }
50 }
51
52
53 void dequeue(){
54 if(isEmpty()){
55 cout<<"\nQueue is empty!\n";
56 return;
57 }
58 else{
59 cout<<"\nElement removed from queue is:
"<<arrayq[front];
60 cout<<"\n";
61 if (front == rear) {
62 front = -1;
63 rear = -1;
64 }
65 else {
66 if(front == MAX - 1)
67 front = 0;
68 else
69 front = front+1;
70 }

IT 201: DATA STRUCTURES AND ALGORITHMS 77


UNIT 1: Data Structures

71
72 }
73 }
74
75 void display(){
76 int i;
77 if(isEmpty()){
78 cout<<"\nQueue is empty!\n";
79 return;
80 }
81 else{
82 cout<<"\nElements in queue: ";
83 if (front<=rear){
84 for(i=front; i<=rear; i++)
85 cout<<arrayq[i]<<" ";
86 cout<<"\n";
87 }
88 else {
89 while (front <= MAX - 1) {
90 cout<<arrayq[front]<<" ";
91 front++;
92 }
93 front = 0;
94 while (front <= rear) {
95 cout<<arrayq[front]<<" ";
96 front++;
97 }
98 }
99 cout<<endl;
100 }
101
102 }
103
104 void peek(){
105 if(isEmpty()){
106 cout<<"\nQueue is empty!\n";
107 return;
108 }
109 else{
110 cout<< "\nFront element is: " << arrayq[front];}
111 cout<<"\n";
112 }
113
114 void index() //checks the value in the [0] index {
115 if(isEmpty()){
116 cout<<"\nQueue is empty!\n";
117 return;
118 }
119 else{
120 cout<<"\nIndex [0] in array: " << arrayq[0];
121 cout<<"\n";
122 }
123 }
124
125 int main(){
126 int ch;
127 while(1){
128 cout<<"\n[1] Add\n";
129 cout<<"\n[2] Delete\n";

IT 201: DATA STRUCTURES AND ALGORITHMS 78


UNIT 1: Data Structures

Output:

Figure 10: Shows the result after adding an element

IT 201: DATA STRUCTURES AND ALGORITHMS 79


UNIT 1: Data Structures

Figure 10.1: Shows the result when the queue is full. It also
shows the queue elements.

Figure 10.2: Shows the result after deleting an element

IT 201: DATA STRUCTURES AND ALGORITHMS 80


UNIT 1: Data Structures

Figure 10.3: Shows the queues remained after dequeuing

Figure 10.4: Shows the queue elements after adding new


elements

Figure 10.5: Shows the current front element

IT 201: DATA STRUCTURES AND ALGORITHMS 81


UNIT 1: Data Structures

Figure 10.6: Shows the element in the 0th location of the


array.

Applications:

1. Memory Management: The unused memory locations in the case of ordinary


queues can be utilized in circular queues.

2. Traffic system: In computer-controlled traffic system, circular queues are


used to switch on the traffic lights one by one repeatedly as per the time set.

3. CPU Scheduling: Operating systems often maintain a queue of processes


that are ready to execute or that are waiting for a particular event to occur.

IT 201: DATA STRUCTURES AND ALGORITHMS 82


UNIT 1: Data Structures

Priority Queues

What is a Priority Queue?

In a normal queue, the service is provided on the basis of First-In-First-Out. But,


in a priority queue, service isn’t provided on the basis of First-In-First-Out service.
Priority Queue is more specialized data structure than Queue. From the word “priority”,
each element was based on the urgency of the need. Like ordinary queue, priority
queue has same method but with a major difference. In Priority queue, items are
ordered by key value so that item with the lowest value of key is at front and item with
the highest value of key is at rear or vice versa. We assign priority to item based on its
key value. The lower the value, higher the priority. Always remember that in priority
queue:

▪ An element with higher priority is processed before other elements with lower
priority.
▪ Elements with the same priority are processed on First-In-First-Out service basis.

Figure 11: Shows the added element with priority

Figure 11.1: Shows the elements added and sorted based on


their priority

IT 201: DATA STRUCTURES AND ALGORITHMS 83


UNIT 1: Data Structures

Figure 11.2: Shows the elements added and sorted based on


their priority

Figure 11.3: Shows the element deleted that has higher priority

Other applications of priority queues are found in long term scheduling of jobs
processed in a computer. In practice, short processes are given a priority over long
processes as it improves the average response of the system.

Advantages of the priority queue

Items are given weight, which allows them to move towards the head of the
queue rather than being on the tail of the queue as would happen in the regular queue.

Disadvantages of the priority queue

Inserting an item to the queue doesn’t take a constant time like regular queues,
because we have to apply insertion sort as we insert an item on the basis of their
priority.

Algorithm

Begin
class Priority_Queue has following functions:
function insert() to insert items at priority queue with their priorities:
(See line 27 in the example code)
1) If queue is empty insert data from the left end of the queue.
2) If queue currently have some data then insert the new element at the end of
those elements having priority
same with the new elements and also before all the elements having priority
lesser than the current priority of the new element.

IT 201: DATA STRUCTURES AND ALGORITHMS 84


UNIT 1: Data Structures

function delete() to delete items from queue.


(See line 53 in the example code)
If queue is completely empty, print underflow otherwise delete the front
element and update front.
End

The highest priority element is in the front of the queue. On deletion, the first
element of the queue is being removed from the queue. Element with the same priority
is sorted based on the FIFO.

In this example code, it will show how the insertion and deletion of an element
in a priority queue is applied using C++.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 if(isFull()){
30
31
32
33
34
35 cin>>ins_item;
36
37
38 if(front==-1){
39
40
41
42
43
44
IT 201: DATA STRUCTURES AND ALGORITHMS 85
UNIT 1: Data Structures

45 else
46 rear = rear + 1;
47 }
48 arrayq[rear]=ins_item;
49 }
50 }
51
52
53 void dequeue(){
54 if(isEmpty()){
55 cout<<"\nQueue is empty!\n";
56 return;
57 }
58 else{
59 cout<<"\nElement removed from queue is:
"<<arrayq[front];
60 cout<<"\n";
61 if (front == rear) {
62 front = -1;
63 rear = -1;
64 }
65 else {
66 if(front == MAX - 1)
67 front = 0;
68 else
69 front = front+1;
70 }
71
72 }
73 }
74
75 void display(){
76 int i;
77 if(isEmpty()){
78 cout<<"\nQueue is empty!\n";
79 return;
80 }
81 else{
82 cout<<"\nElements in queue: ";
83 if (front<=rear){
84 for(i=front; i<=rear; i++)
85 cout<<arrayq[i]<<" ";
86 cout<<"\n";
87 }
88 else {
89 while (front <= MAX - 1) {
90 cout<<arrayq[front]<<" ";
91 front++;
92 }
93 front = 0;
94 while (front <= rear) {
95 cout<<arrayq[front]<<" ";
96 front++;
97 }
98 }
99 cout<<endl;
100 }
101
102 }

IT 201: DATA STRUCTURES AND ALGORITHMS 86


UNIT 1: Data Structures

IT 201: DATA STRUCTURES AND ALGORITHMS 87


UNIT 1: Data Structures

Output:

Figure 12: Shows the enqueuing of elements with priority

Figure 12.1: Shows the elements from the queue and sorted
based on their priority

Figure 12.2: Shows the dequeuing of an element based on its


priority 88
IT 201: DATA STRUCTURES AND ALGORITHMS
UNIT 1: Data Structures

Figure 12.3: Shows the remaining elements from the queue.

IT 201: DATA STRUCTURES AND ALGORITHMS 89


UNIT 1: Data Structures

REFERENCES
Data Structure and Algorithms – Queues. (n.d.). Retrieved August 2020, from
Tutorials Point:
https://www.tutorialspoint.com/data_structures_algorithms/dsa_queue.htm#:
~:text=Queue%20is%20an%20abstract%20data,first%20will%20be%20acc
essed%20first.

Ahlawat, A. (n.d.) Queue Data Structure | Study Tonight. Retrieved August 2020,
from Study Tonight: https://www.studytonight.com/data-structures/queue-
data-structure

Queue Data Structure on C++ with Illustration. (2020, August 2). Retrieved August
2020, from Software Testing Help:
https://www.softwaretestinghelp.com/queue-in-
cpp/#:~:text=The%20operation%20of%20adding%20%2Finserting,that%20t
he%20queue%20is%20full.

Circular Queue | Set 1 (Introduction and Array Implementation). (2020, August 19)
Retrieved August 2020 from GeeksForGeeks:
https://www.geeksforgeeks.org/circular-queue-set-1-introduction-array-
implementation/

Circular Queue Data Structure. (n.d.). Retrieved August 2020, from Programiz:
https://www.programiz.com/dsa/circular-queue

Mishra, A. (n.d.) Priority Queue in C and C++. Retrieved August 2020 from The
Crazy Programmer: https://www.thecrazyprogrammer.com/2017/06/priority-
queue-c-c.html

Lathiya, A. (2019, October 18) Priority Queue In C++ Example | C++ Priority Queue
Program. Retrieved August 2020 from AppDividend:
https://appdividend.com/2019/10/09/priority-queue-in-cpp-example-cpp-
priority-queue-program/

IT 201: DATA STRUCTURES AND ALGORITHMS 97

You might also like