You are on page 1of 6

QUEUES: Array Implementation

A queue is an abstract data type (ADT)that follows the principle of FIFO


(First In, First Out). Unlike a stack in which add and remove operations are
only performed on one end (the top), operations occur at BOTH ends of a
queue. Data is added to back or rear of a queue, and data is removed from the
front or head of the queue. Imagine a line at a drive-thru: the cars line up
in order of who arrives first. When the customer at the front of the line is
served, the following cars move up.

The following operations can be performed on a queue:


1. enqueue() − add (store) an item to the queue
2. dequeue() − remove (access) an item from the queue
3. peek() − Gets the element at the front of the queue without remo ving it.
4. isFull() − Checks if the queue is full.
5. isEmpty() − Checks if the queue is empty.

We use the following code in C to implement a stack using arrays:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX 6

int queue[MAX]; //declare an array called 'queue' of size MAX


int front = 0; //variable to store the index of the element at the front of the queue
int rear = -1; // variable to store the index of the last element in the queue
int itemCount = 0; //variable to keep track of the total number of items in the queue

/*This function allows the user to view or 'peek' the first element in the queue,
i.e., the element at the front */
int peek() {
return queue[front];
}

/*This function checks if the queue is empty by checking the itemCount variable. If
there are 0 items in the queue, it is empty */
bool isEmpty() {
return itemCount == 0;
//shortened form of if (itemCount==0) return true; else return //false;
}

/*This function checks if the queue is full. If the number of items in the queue is
equal to its maximum capacity upon declaration, the queue is full */
bool isFull() {
return itemCount == MAX;
//shortened form of if (itemCount==MAX) return true; else return //false;
}

© Rafena Mustapha
/*This function returns the total number of elements in the queue*/
int size() {
return itemCount;
}

/*This functions adds a new element to the REAR of the queue if the queue is not
already full. */
void enqueue(int data) {

if(!isFull()) {//check that the queue is not already full

if(rear == MAX-1) { //check if the element currently at the end of line is in


the LAST location. ie, the index at MAX-1. This means that we cannot add any more
elements to the back of the line;
rear = -1;// we have to refactor rear to start adding to the front of the
line IF there is space. Hence, we set rear=-1
}

queue[++rear] = data;//move the rear index to the next free location in the
queue and then add the data to that new location
/* This is condensed code for:
rear = rear + 1; OR rear++;
queue[rear] = data; */
itemCount++; //update itemCount to show the size of the queue has increased
} else {
printf("Queue is full!\n");
}
}

/*This function removes an element from the front of the queue IF the queue is not
already empty*/
int dequeue() {
int data = queue[front++]; //grab the value that is at the front of the queue and
then move the front index to the next element in the queue. The next person in line is
at the front once the current front has been removed
/*This is condensed code for:
int data = queue[front];
front++; OR front = front + 1; */
if (!(isEmpty())){//check if the queue is already empty
if(front == MAX) { //if we have reached the last person in the line, i.e,
there is only one element left in the line
front = 0;//reset the front index to 0. Once the only item in the line has been
removed we will have to add any new item to the first index of the queue which is 0
}
itemCount--; //update itemCount to show the reduction of the size of the
array
return data;//return the item that was removed
} else {
printf("Queue is empty!\n");
}

int main() {
/* insert 5 items */
enqueue(3);
enqueue(5);
enqueue(9);
enqueue(1);
enqueue(12);
enqueue(15);

if(isFull()) {

© Rafena Mustapha
printf("Queue is full!\n");
}

// remove one item


int num = dequeue();
printf("Element removed: %d\n",num);
num = dequeue();
printf("Element removed: %d\n",num);
num = dequeue();
num = dequeue();
num = dequeue();
num = dequeue();
num = dequeue();

enqueue(16);
enqueue(17);
enqueue(18);
enqueue(19);
printf("Element at front: %d\n",peek());

for (int i = 0; i <7; i++){


printf("%d", i);
printf("\t%d\n", queue[i]);
}
}

© Rafena Mustapha
An empty queue

F R = -1;
queue itemCount = 0;
0 1 2 3 4 5

A partially filled queue

F R
queue 10 20 30 40 itemCount = 4;
0 1 2 3 4 5

Removing an item from a queue

int data = queue[front++];

F R
queue 10 20 30 40 itemCount = 4;
0 1 2 3 4 5

data = 10

à F R
queue 10 20 30 40 itemCount = 3;
0 1 2 3 4 5

NOTE: 10 does not go away; however, it can now


be overwritten since the front index pointer
has been moved forward to the next in line

F R
queue 10 20 30 40
0 1 2 3 4 5

NOTE: While it is possible to move every item in the queue forward one space
each time an item is removed, it is not efficient coding because on a larger
data set, say 1000, we would have to move 1000 items forward. This is called
linear complexity, where the efficiency of output depends on the size of the
input. Programmers generally try to avoid linear complexity, although it is
considered better than higher degrees of complexity.

It is easier for us to increment the single variable that stores the index of
the first item in the queue. This makes for much more efficient coding.

© Rafena Mustapha
SPECIAL CASE

Notice the change in procedure if we are removing the very last item in the
queue:

F R BOTH the front and rear variables will


queue 60 have the same index value if it is the
0 1 2 3 4 5 only remaining item in the queue

itemCount = 1;

F R After int data = queue[front++]; front now


queue 60 has the value 6 which is the max capacity
0 1 2 3 4 5 of our queue

itemCount = 0;

if(front == MAX)
front =0;//At this point we reset our front to first index in the queue

This essentially removes the last item and resets the front index value. The
60 can now be overwritten.

Notice: We can also remove items without worry about the spaces created in
the front index values. As long as the variable front contains the correct
index of the item that is at the front to be removed, the code works
efficiently.

© Rafena Mustapha
Adding an item to a queue

queue[++rear] = data;

F à R
queue 10 20 30 40 itemCount = 4;
0 1 2 3 4 5
itemCount++;
F à R
queue 10 20 30 40 50 itemCount = 5;
0 1 2 3 4 5
if we call enqueue(50), 50 is added to
the rear of the queue

SPECIAL CASE

If there is space in front of the queue, the following occurs:

F rear = -1;
queue 40 50 60 itemCount = 3;
0 1 2 3 4 5

If we call enqueue(70), rear gets updated to index 0

queue[++rear] = data;

R F
queue 70 40 50 60 itemCount = 4;
0 1 2 3 4 5

QUEUE OVERFLOW AND QUEUE UNDERFLOW

Overflow and underflow are easily handled in this implementation using


itemCount variable. The queue is empty is itemCount = 0 and it is full if
itemCount = the maximum capacity of the queue.

© Rafena Mustapha

You might also like