Linear and Circular Queue Notes
Linear and Circular Queue Notes
QUEUES
Queue is a linear data structure in which data inserted into one end and deleted from another
end. This structure follows the First In, First Out (FIFO) principle, meaning the first element
that is inserted will be the first one to be removed.
The process of adding an element into a queue is known as the enqueue operation, while the
process of removing an element is known as the dequeue operation. A Queue maintains two
pointers - the front pointer points to the first inserted element, while the rear pointer points to
the last inserted element.
Design A Stack is a linear data structure where A Queue is also a linear data structure, but
removal and insertion occur at the removal and insertion happen at different
same end. ends.
Principle A Stack follows the Last In, First Out A Queue follows the First In, First Out (FIFO)
(LIFO) principle, meaning the most principle, meaning the earliest inserted
recently inserted element is removed element is removed first.
first.
Pointers A Stack uses a single pointer, the top, A Queue uses two pointers, the front and
to keep track of the most recently the rear, to keep track of the first and last
added element. inserted elements respectively.
Structure In a Stack, both insertion and deletion In a Queue, insertion happens at the rear end
happen at the same end, known as the and deletion happens at the front end.
top.
Full A Stack is considered full when top A Queue is considered full when rear equals
Condition equals max-1. max-1.
Check
Empty A Stack is considered empty when top A Queue is considered empty when front
Condition equals -1. equals rear+1 or front equals -1.
Check
Variants A Stack does not have any variants. A Queue has three variants - circular queue,
priority queue, and double-ended queue.
Queue ADT
The following operations make a queue an ADT. Insertions and deletions in the queue must
follow the FIFO scheme.
Main Queue Operations
• EnQueue(int data): Inserts an element at the end of the queue
• int DeQueue(): Removes and returns the element at the front of the queue
Auxiliary Queue Operations
• int Front(): Returns the element at the front without removing it.
• int QueueSize(): Returns the number of elements stored in the queue
• int IsEmptyQueueQ: Indicates whether no elements are stored in the queue or not.
Operations on QUEUE:
A queue is an object or more specifically an abstract data structure (ADT) that allows the
following operations:
• Enqueue or insertion: which inserts an element at the end of the queue.
• Dequeue or deletion: which deletes an element at the start of the queue.
Again, insert another element 33 to the queue. The status of the queue is:
Now, delete an element. The element deleted is the element at the front of the queue.So the
status of the queue is:
Again, delete an element. The element to be deleted is always pointed to by the FRONT pointer.
So, 22 is deleted. The queue status is as follows:
Now, insert new elements 44 and 55 into the queue. The queue status is: 18
Next insert another element, say 66 to the queue. We cannot insert 66 to the queue as the rear
crossed the maximum size of the queue (i.e., 5). There will be queue full signal. The queue
status is as follows:
Now it is not possible to insert an element 66 even though there are two vacant positions in the
linear queue. To overcome this problem the elements of the queue are to be shifted towards the
beginning of the queue so that it creates vacant position at the rear end. Then the FRONT and
REAR are to be adjusted properly. The element 66 can be inserted at the rear end. After this
operation, the queue status is as follows:
This difficulty can overcome if we treat queue position with index 0 as a position that comes
after position with index 4 i.e., we treat the queue as a circular queue.
char InsertQ(char x)
{
if(Isfull())
{
printf("\n Queue full");
return x;
}
rear++;
Que[rear]=x;
}
char DeleteQ()
{
char x;
if(Isempty())
{
printf("\n Queue is empty");
exit(0);
}
x=Que[front];
front++;
return x;
}
void Display()
{
int i;
if(Isempty())
{
printf("\n Queue is empty");
return;
}
printf("\n Elements in the Queue are :\n");
for(i=front;i<=rear;i++)
{
fflush(stdin);
putchar(Que[i]);
}
}
struct Node
{
int data;
struct Node *link;
}*front = NULL,*rear = NULL;
void enque(int);
void deque();
void display();
int main()
{
int choice, value;
printf("\n:: Queue Implementation using Linked List ::\n");
while(1)
{
printf("\n****** MENU ******\n");
printf("1. Insert\n2. Delete\n3. Display\n4. Exit\n");
printf("Enter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("Enter the value to be insert: ");
scanf("%d", &value);
enque(value);
break;
case 2: deque();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("\nWrong selection!!! Please try again!!!\n");
}
}
return 0;
}
void enque(int value)
{
struct Node *newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode -> link = NULL;
if(front == NULL)
front = rear = newNode;
else{
rear -> link = newNode;
rear = newNode;
}
printf("\nInsertion is Success!!!\n");
}
void deque()
{
if(front == NULL)
printf("\nQueue is Empty!!!\n");
else{
struct Node *temp = front;
front = front -> link;
printf("\nDeleted element: %d\n", temp->data);
free(temp);
}
}
void display()
{
if(front == NULL)
printf("\nQueue is Empty!!!\n");
else{
struct Node *temp = front;
while(temp->link != NULL){
printf("%d--->",temp->data);
temp = temp -> link;
}
printf("%d--->NULL\n",temp->data);
}
}
CIRCULAR QUEUES
• The queue that we implemented using an array suffers from one limitation. In that
implementation there is a possibility that the queue is reported as full (since rear has
reached the end of the array), even though in actuality there might be empty slots at the
beginning of the queue.
• To overcome this limitation, we can implement the queue as a circular queue. Here as we
go on adding elements to the queue and reach the end of the array, the next element is
stored in the first slot the array (provided it is free).
• Suppose an array arr of n elements is used to implement a circular queue we may reach
arr[n-1]. We cannot add any more elements to the queue since we have reached at the end
of the array. Instead of reporting the queue as full, if some elements in the queue have been
deleted then there might be empty slots at the beginning of the queue.
• In such a case these slots would be filled by new elements being added to the queue. In
short just because we have reached the end of the array, the queue would not be reported
as full. The queue would be reported as full only when all the slots in the array stand
occupied.
• For example, let us consider a linear queue status as follows:
Next insert another element, say 66 to the queue. We cannot insert 66 to the queue as the
rear crossed the maximum size of the queue (i.e., 5). There will be queue full signal. The
queue status is as follows:
This difficulty can be overcome if we treat queue position with index zero as a position
that comes after position with index four then we treat the queue as a circular queue. In
circular queue if we reach the end for inserting elements to it, it is possible to insert new
elements if the slots at the beginning of the circular queue are empty.
Representation of Circular Queue:
Let us consider a circular queue, which can hold maximum (MAX) of six elements.
Initially the queue is empty.
Now, insert 11 to the circular queue. Then circular queue status will be:
Insert new elements 22, 33, 44 and 55 into the circular queue. The circular queue status
is:
Now, delete an element. The element deleted is the element at the front of the circular
queue. So, 11 is deleted. The circular queue status is as follows:
Again, delete an element. The element to be deleted is always pointed to by the FRONT
pointer. So, 22 is deleted. The circular queue status is as follows:
Again, insert another element 66 to the circular queue. The status of the circular queue is:
22
Now, insert new elements 77 and 88 into the circular queue. The circular queue status is:
Now, if we insert an element to the circular queue, as COUNT = MAX we cannot add the
element to circular queue. So, the circular queue is full.
#include<stdio.h>
#include<stdlib.h>
#define SIZE 3
int cq[SIZE];
int front = -1, rear = -1;
void insert_cq();
int delete_cq();
void display();
int main()
{
int ch;
printf("\nCircular Queue operations");
printf("\n Enter 1 to insert into queue");
printf("\n Enter 2 to delete element");
printf("\n Enter 3 to display element");
printf("\n Enter 4 to exit");
do
{
printf("\n Enter your choice: ");
scanf("%d",&ch);
switch(ch)
{
case 1: insert_cq();
break;
case 2: delete_cq();
break;
case 3: display();
break;
case 4:exit(0);
default:printf("Invalid input \n");
}
} while(1);
return 0;
}
int isFull() {
if ((front == rear + 1) || (front == 0 && rear == SIZE - 1)) return 1;
return 0;
}
int isEmpty() {
if (front == -1) return 1;
return 0;
}
void insert_cq()
{
int x;
if (isFull())
printf("\n Queue is full!! \n");
else
{
printf("\n Enter a value to insert: ");
scanf("%d",&x);
if (front == -1) front = 0;
rear = (rear + 1) % SIZE;
cq[rear] = x;
}
}
int delete_cq()
{
int x;
if (isEmpty())
{
printf("\n Queue is empty !! \n");
return (-1);
}
else
{
x= cq[front];
if (front == rear)
{
front = -1;
rear = -1;
}
else {
front = (front + 1) % SIZE;
}
printf("\n Deleted element -> %d \n", x);
return (x);
}
}
void display ()
{
int i;
if (isEmpty())
printf(" \n Empty Queue\n");
else {
printf("\n Front -> %d ", front);
printf("\n Items -> ");
for (i = front; i != rear; i = (i + 1) % SIZE) {
printf("%d ", cq[i]);
}
printf("%d ", cq[i]);
printf("\n Rear -> %d \n", rear);
}
}
Advantages of Circular queue over linear queue:
In a linear queue with max. size 5, after inserting element at the last location (4) of array, the
elements can’t be inserted, because in a queue the new elements are always inserted from the
rear end, and rear here indicates to last location of the array (location with subscript 4) even if
the starting locations before front are free. But in a circular queue, if there is element at the last
location of queue, then we can insert a new element at the beginning of the array.