0% found this document useful (0 votes)
213 views

Queues in Data Structures Using C

Queue is a first-in, first-out (FIFO) data structure where elements are inserted at the rear and deleted from the front. A linear queue uses an array with front and rear pointers, where front points to the first element and rear points to the last. Main queue operations are insert, which increments rear and inserts at that index; delete, which returns the element at front and increments front; and checks for overflow if rear reaches the end of the array and underflow if front meets or passes rear.

Uploaded by

Anurag R Swamy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
213 views

Queues in Data Structures Using C

Queue is a first-in, first-out (FIFO) data structure where elements are inserted at the rear and deleted from the front. A linear queue uses an array with front and rear pointers, where front points to the first element and rear points to the last. Main queue operations are insert, which increments rear and inserts at that index; delete, which returns the element at front and increments front; and checks for overflow if rear reaches the end of the array and underflow if front meets or passes rear.

Uploaded by

Anurag R Swamy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Queues:-

Queue is a special type of data structure ( an ordered collection of items ) where elements are inserted from one
end and elements are deleted from other end. The end at which new elements are added is called rear and the end from
which elements are deleted is called the front. So , Queue is called First In First Out ( FIFO ) data structure.

Linear Queue ( Ordinary Queue )


Types of Queues Circular Queue
Double Ended Queue ( deque )
Linear Queue ( Ordinary Queue ):-
Queue can be implemented using linear list. For example , the queue q = {A0 , A1 , A2 , ………..An-1 } is pictorially
represented as shown below ;
Delete from front A0 A1 A2 …… An-3 An-2 An-1 Insert at rear
0 1 2 …… n-3 n-2 n-1

front rear
from above fig., we observe that ,
1. The queue is represented sequentially using one-dimensional array with two variables front and rear.
2. The variable front is used as index to access the first element.
3. The variable rear is used as index to access the last element.
4. Elements are inserted into the queue in the order A0 , A1 , A2 , ………….. An-1 . i.e. we insert A0 first , A1 next
and so on. Item An-1 is inserted at the end.
5. Element A0 is the first element and it is at the front of queue.
6. Element An-1 is the last element inserted and it is at the rear end of queue.
7. Items are deleted from the front end in the order A0 , A1 , A2 , ………….. An-1.

Various operations performed on queue are ;


Create : initializing the queue.
Insert : an element is inserted from rear end.
Delete : an element is deleted from front end.
Overflow : if queue is full and we try to insert an item , overflow condition occurs.
Underflow : if queue is empty and try to delete an item, underflow condition occurs.

1. Create Queue :
A. The createq ( QUE_SIZE ) function can be implemented as a single dimensional array q[ QUE_SIZE]
where QUE_SIZE is a symbolic constant and specifies the maximum number of elements that can be
inserted into the queue. This can be defined as shown below ,
#define QUE_SIZE 5
B. q is an array which is used to hold the elements of the queue as shown below ;
a. q[ 0 ] holds the 0th element.
b. q[ 1 ] holds the1st element.
c. q[ 2 ] holds the 2nd element , so on can be defined as int q[ QUE_SIZE ] ;
C. The variable front and rear are associated with array q and holds the index of the first element and
index of the rear element. If itemis the element that is inserted into the queue for the first time, then
we write as q[ 0 ] = item

rear & front


means, the value of front and rear is 0 when an item is inserted for the first time from the rear end. Since
we are inserting from the rear end , before inserting the item, the value of rear must be -1 and front has not been
changed. That is front and rear can be initialized as ;
int front = 0 ; // queue is empty , no elements in queue.
int rear = -1 ;

SASA FACILITY MANAGEMENTS Page 42 of 81


So, createq can be implemented as ,
#define QUE_SIZE 5
int q [ QUE_SIZE ] ;
int front = 0 ;
int rear = -1 ;
2. Insert ( ) :
Before inserting , we check whether sufficient space is available in the queue( by checking full or not ).
Isfull () :-
For example, if QUE_SIZE is 4 , the items 30 , 20 , 25 and 10 are inserted into the queue one after
the other as shown below :
Empty Queue After inserting 30
30
-1 0 1 2 3 -1 0 1 2 3

rear front front& rear

After inserting 20 After inserting 25

30 20 30 20 25
-1 0 1 2 3 -1 0 1 2 3

front rear front rear

After inserting 10 inserting 25 result in overflow

30 20 25 10 30 20 25 10
-1 0 1 2 3 -1 0 1 2 3

front rear front rear


QUE_SIZE = 4
So , if rear is same as QUE_SIZE -1 , then queue is full. In such situation, we return 1 indicating queue is full
otherwise 0 indicating queue is not full.
The code can be return as ,
/*Check overflow of queue */
If ( rear == QUE_SIZE -1 ) {
printf ( “Queue Overflow\n” ) ;
return ;
}
When above condition fails, we can insert an item into the queue. To insert an item we have to increment
rear by 1 as ,
rear = rear + 1 ;
then item can be inserted at the rear end of queue using :
q [ rear ] = item ;
the code can be return as ,
void insert_q ( ) {
if ( rear == QUE_SIZE -1 ) {
printf ( “Queue Overflow!” ) ;
return ;
}
q [ ++rear ] = item ;
}

SASA FACILITY MANAGEMENTS Page 43 of 81


3. Delete ( ):
In a queue, an element is always deleted from the front end. Before deleting, we should check whether
queue is empty.
Isempty( ) :-
For example, assume that the ites 30 , 20 , 25 , 10 are already inserted into the queue then all
items can be deleted one after the other from the front end of the queue as shown,
Queue full After deleting 30

30 20 25 10 20 25 10
-1 0 1 2 3 -1 0 1 2 3

front rear front rear

After deleting 20 After deleting 25

25 10 10
-1 0 1 2 3 -1 0 1 2 3

front rear front &rear

After deleting 10 , queue is empty Initial Empty Queue

-1 0 1 2 3 -1 0 1 2 3

rear front rear front


As the items are deleted , the value of front is incremented by 1 and when queue is empty, the value of
front is greater than value of rear. So , before deleting , we check whether queue is empty.
The code can be written as ,
if ( front > rear ) return -1 ;
When above condition fails, we can delete an item from front end of queue. For this to happen, we have
to access and return the first element and increment value of front by 1 as shown,
return q [ front++ ] ;
the complete code can be written as ,
int delete_q ( ) {
if ( front > rear )
return -1 ;
return q [ front ++ ] ;
}
4. Display :
In this procedure, if the queue already has some items , all those items are displayed one after the other. If
no items are present, the appropriate error message is displayed.
Assume that the queue contain 3 elements as shown in figure.,
20 25 10
-1 0 1 2 3 4

front rear
the content of the queue are displayed from the front to rear. So,
first item to be displayed is 20
next item to be displayed is 25
final item to be displayed is 10

SASA FACILITY MANAGEMENTS Page 44 of 81


now the code can be written as ,
for ( i = front ; i<= rear ; i++ ) {
printf ( “%d\n” , q [ i ] ) ;
the above statement should not be executed when stack is empty i.e., when front >= rear.
the complete code can be written as ,
void display_q ( ) {
int i ;
if ( front > rear ) {
printf ( “ Queue is Empty !!!” ) ;
return ;
}
printf ( “ contents of the queue \n” ) ;
for ( i = front ; i <= rear ; i++ )
printf ( “%d\n” , q [ i ] ) ;
}

/******* **Program to implement queue operations by passing parameters ********/


#define QUE_SIZE 5
void inset_q ( int item , int *rear , int *q ) ;
int delete_q ( int *front , int *rear , int *q ) ;
void display_q ( int front , int rear , int q[ ] ) ;

void main ( ) {
int ch , item , front , rear , q [ 10 ] ;
/**** Intially Queue is Empty ****/
front = 0 ; // front end of queue
rear = 0 ; // rear end of queue
for ( ; ; ) {
printf ( “ \n 1. Insert \t 2. Delete \t 3. Display 4. Exit \n Enter Your Choice :\t “ ) ;
scanf ( “%d” , &ch ) ;
switch ( ch ) {
case 1 : printf ( “Enter the item to be inserted :\t” ) ;
scanf ( “%d”, &item ) ;
inset_q ( item , &rear , q ) ;
break ;
case 2 : item = delete_q ( &front , &rear , q );
if ( item == -1 )
printf ( “ Queue is empty “ ) ;
else
printf ( “Deleted item :\t%d” , item ) ;
break ;
case 3 : diplay_q ( front , rear , q ) ;
break ;
case 4 : exit ( 0 ) ;
} // switch
} //for loop
} // main

/*************** inset_q ( ) **************/


void inset_q ( int item , int *rear , int *q ) {
/******** check for overflow *********/
if ( *rear == QUE_SIZE -1 ) {
printf ( “\nQueue Overflow!!!” ) ;
return ;
}
q [ ++(*rear) ] = item ;
}

SASA FACILITY MANAGEMENTS Page 45 of 81


/*************** delete_q ( ) **************/
int delete_q ( int *front , int *rear , int *q ) {
/******** check for underflow *********/
if ( *front > *rear )
return -1 ;
return q [ (*front) ++ ] ;
}
/*************** display_q ( ) **************/
void display_q ( int front , int rear , int q[ ] ) {
register unsigned int i ;
/******** check for underflow *********/
if ( front > rear ){
printf ( “ Queue is empty!!!” ) ;
return -1 ;
}
/**** display contents of queue ****/
printf ( “\nContents of queue :\n” ) ;
for ( i = front ; i <= rear ; i++ )
printf ( “%d\t” , q [ i ] ) ;
}

/****** End of Program to implement queue operations by passing parameters *****/

Disadvantage of Linear Queue :-


Consider the queue shown below ,
front rear

0 1 2 3 4
30 40 50
The above situation arises when 5 elements say 10 20 30 40 50 are inserted and then deleting first 2 items 10 and
20. Now , if we try to insert an item we get the message , queue Overflow.
But in the above situation, rear insertion is denied even if space is available at the front end. This is because e in
our function , before inserting an element , we test whether rear is equal to QUE_SIZE -1. If so, we say queue is full and
cannot insert. This disadvantage can be overcome using 2 methods.
Method 1 : shift left -
After deleting the element from the front , shift all remaining elements to the left , as shown ;
front rear front rear

0 1 2 3 4 0 1 2 3 4
10 20 30 40 50 20 30 40 50
After inserting 10 20 30 40 50 After deleting 10 , shift remaining elements to left

front rear ront rear

0 1 2 3 4 0 1 2 3 4
30 40 50 40 50
After deleting 20 , shift remaining After deleting 30 , shift remaining
elements to left elements to left

Each time when an item is deleted , all the elements towards the right are moved to left by one position
and rear is decremented by 1. But, shifting the data is costly in terms of computer time if the data being stored is
very large. So , this method is not recommended.

SASA FACILITY MANAGEMENTS Page 46 of 81


Method 2 : using Circular Representation -

Circular Queue :-
If the elements of a given queue can be stored efficiently in an array so as to “wrap around” so that end of the
queue is followed by the front of queue then it is called circular queue.
The pictorial representation and its equivalent representation using an array are given side by side in figure below,
rear
2
3 q 10 20 30 40 50
30
0 1 2 3 4
20
1 front rear
4 10

0 front
This circular representation allows the entire array to store the elements without shifting any data
within the queue. This is efficient way of implementing queues.

Create :
The create function can be implemented as a single dimensional array q [ QUE_SIZE ] where,
1. QUE_SIZE is a symbolic constant and specifies the maximum number of elements can be inserted into
the queue, defined as,
#define QUE_SIZE 5
2. q is an array which is used to hold the elements of the queue and defined as,
int q [ QUE_SIZE ] ;
when queue is empty, the values of index variables front and rear are initialized as,
int front = 0 , rear = -1 ;
using values of front and rear , it is very difficult to say when queue is full and when queue is
empty. For this purpose, we also use another variable count which keeps track number of elements in the
queue. When no elements are there in queue, the number of elements will be 0 and hence count is
initialized to 0 as,
int count = 0 ; // Queue is empty
so, create_q can be implemented as ,
#defined QUE_SIZE 5
int q[ QUE_SIZE ] ; // as global variables
int front = 0 , rear = -1 , count = 0 ; // as global variables
Insert Circular Queue :
Various steps to be followed while inseting the elements into queues ,
1. Check for Overflow :before inserting, we check whether sufficient space is available in the queue. This can
be done using the code as,
if ( count == QUE_SIZE ){
printf ( “ Queue is full\n” ) ;
return ;
}
2. Insert item :Increment rear by 1 and then take the mod operation and then insert the item as,
rear = ( rear + 1 ) % QUE_SIZE ;
q [ rear ] = item ;
3. Update count : as we insert an element into queue, we update count by 1 as,
count++ ;
the complete code can be written as,
void insert_cq ( ) {
if ( count == QUE_SIZE ) {
printf ( “\nQueue Overflow!!!” ) ;
return ;
}

SASA FACILITY MANAGEMENTS Page 47 of 81


rear = ( rear + 1 ) % QUE_SIZE ;
q [ rear ] = item ;
count ++ ;
}
Delete Circular Queue:
Various steps to be followed while deleting the elements from the queue ,
1. Check for underflow : Before deleting an element from queue, we check whether queue is empty or not.
This can be done by,
if ( count == 0 ) return -1 ;
2. Access the first item : accessing the element using index front and then updating front by adding 1 to it
and taking the mod.
item = q [ front ] ;
front = ( front + 1 ) % QUE_SIZE ; // front contains index of next element
3. Update count : as we delete an element from queue, decrement count by 1 as,
count -- ;
4. Return element which was at the front end using the statement,
return item ;
the complete code can be written as,
int delete_cq ( ) {
if ( count == 0 )
return -1 ;
item = q [ front ] ;
front = ( front + 1 ) % QUE_SIZE ;
count -- ;
return ( item ) ;
}
Display Circular Queue :
Various steps to be followed while deleting the elements from the queue ,
1. Check for underflow : achieved using the following statement :
if ( count == 0 ) {
printf ( “ queue is empty\n” ) ;
return ;
}
2. Display :starts from front index. After displaying q[ front ] we have to update front by 1 ( i.e., incrementing
front by 1 and then taking the modulus ). The procedure is repeated for count number of times ( as count
contains the number of elements in queue ).
for ( i = 1 ; i <= count ; i++ ) {
printf ( “%d\n” , q [ i ] ) ;
front = ( front + 1 ) % QUE_SIZE ;
}
So, complete code for display is,
void display ( ) {
int i ;
if ( count == 0 ) {
printf ( “ Queue is Empty !!!” ) ;
return ;
}
printf ( “ Contents of Queue is \n “ ) ;
for ( i =1 ; I <= count ; i++ ) {
printf ( “%d\n” , q[ front ] ) ;
front = ( front + 1 ) % QUE_SIZE ;
}
}

SASA FACILITY MANAGEMENTS Page 48 of 81


/******* **Program to implement Circular Queue operations by passing parameters ********/
#define QUE_SIZE 5
void inset_cq ( int item , int *rear , int *q , int *count) ;
int delete_cq ( int *front , int *count , int q[ ] ) ;
void display_cq ( int front , int count , int q[ ] ) ;

void main ( ) {
int ch , item , front , rear , count , q [ QUE_SIZE ] ;
/**** Intially Queue is Empty ****/
front = 0 ; // front end of queue
rear = -1 ; // rear end of queue
count = 0 ; // empty queue
for ( ; ; ) {
printf ( “ \n 1. Insert \t 2. Delete \t 3. Display 4. Exit \n Enter Your Choice :\t “ ) ;
scanf ( “%d” , &ch ) ;
switch ( ch ) {
case 1 : printf ( “Enter the item to be inserted :\t” ) ;
scanf ( “%d”, &item ) ;
inset_q ( item , &rear , q , &count ) ;
break ;
case 2 : item = delete_cq ( &front , &count , q );
if ( item == -1 )
printf ( “ Queue is empty “ ) ;
else
printf ( “Deleted item :\t%d” , item ) ;
break ;
case 3 : diplay_cq ( front , count , q ) ;
break ;
case 4 : exit ( 0 ) ;
} // switch
} //for loop
} // main
/*************** inset_cq ( ) **************/
void inset_cq (int item , int *rear , int *q , int *count ) {
/******** check for overflow *********/
if ( *count == QUE_SIZE ) {
printf ( “\nQueue Overflow!!!” ) ;
return ;
}
*rear = ( *rear + 1 ) % QUE_SIZE ;
q [ *rear ] = item ;
( *count ) ++ ;
}
/*************** delete_cq ( ) **************/
int delete_cq (int *front , int *count , int q[ ] ) {
int item ;
/******** check for underflow *********/
if ( *count == 0 )
return -1 ;
item = [ *front ] ;
*front = ( *front + 1 ) % QUE_SIZE ;
*count - = 1 ;
return item ;
}
/*************** display_q ( ) **************/
void display_cq (int front , int count , int q[ ] ) {
register unsigned int i ;

SASA FACILITY MANAGEMENTS Page 49 of 81


/******** check for underflow *********/
if ( count == 0 ){
printf ( “ Queue is empty!!!” ) ;
return ;
}
/**** display contents of queue ****/
printf ( “\nContents of queue :\n” ) ;
for ( i = 1 ; i <= count ; i++ ) {
printf ( “%d\t” , q [ front ] ) ;
front = ( front + 1 ) % QUE_SIZE ;
}
}

/****** End of Program to implement Circular Queue operations by passing parameters *****/

/******* **Program to implement Circular Queue operations using Dynamic Array ********/
#define MALLOC ( ptr , n , type ) /** To allocate memory for One or More items of any data type **/ \
ptr = ( type * ) malloc ( n * sizeof ( type ) ) ; \
if ( ptr == NULL ) { \
printf ( “\n INSUFFICIENT MEMORY!”) ; \
getch () ; \
exit ( 0 ) ; \
}
#define REALLOC ( ptr , n , type ) /** To Reallocate memory for One or More items of any data type **/ \
ptr = ( type * ) realloc ( n * sizeof ( type ) ) ; \
if ( ptr == NULL ) { \
printf ( “\n INSUFFICIENT MEMORY!”) ; \
getch () ; \
exit ( 0 ) ; \
}
int QUE_SIZE = 1 ; /* Global Declaration not as #define since we are varying its value.*/
void inset_cq ( int item , int *rear , int *q , int *count) ;
int delete_cq ( int *front , int *count , int q[ ] ) ;
void display_cq ( int front , int count , int q[ ] ) ;
void main ( ) {
int ch , item , front , rear , count , *q ;
/**** Intially Queue is Empty ****/
front = 0 ; // front end of queue
rear = -1 ; // rear end of queue
count = 0 ; // empty queue
MALLOC ( q , 1 , int ) ;
for ( ; ; ) {
printf ( “ \n 1. Insert \t 2. Delete \t 3. Display 4. Exit \n Enter Your Choice :\t “ ) ;
scanf ( “%d” , &ch ) ;
switch ( ch ) {
case 1 : printf ( “Enter the item to be inserted :\t” ) ;
scanf ( “%d”, &item ) ;
inset_cq ( item , &rear , q , &count ) ;
break ;
case 2 : item = delete_cq ( &front , &count , q );
if ( item == -1 )
printf ( “ Queue is empty “ ) ;
else
printf ( “Deleted item :\t%d” , item ) ;

SASA FACILITY MANAGEMENTS Page 50 of 81


break ;
case 3 : diplay_cq ( front , count , q ) ;
break ;
case 4 : exit ( 0 ) ;
} // switch
} //for loop
} // main
/*************** inset_cq ( ) **************/
void inset_cq (int item , int *rear , int *q , int *count ) {
/******** check for overflow *********/
if ( *count == QUE_SIZE ) {
printf ( “\nQueue Overflow!!!” ) ;
printf ( “ Increase Size by 1 \n “ );
QUE_SIZE ++ ;
REALLOC ( *q , QUE_SIZE , int ) ;
}
if ( *front > *rear ) {
for ( i = QUE_SIZE – 2 ; i >= *front ; i-- )
q [ i+1 ] = q[ i ] ;
( *front )++ ;
}
*rear = ( *rear + 1 ) % QUE_SIZE ;
q [ *rear ] = item ;
( *count ) ++ ;
}
/*************** delete_cq ( ) **************/
int delete_cq (int *front , int *count , int q[ ] ) {
int item ;
/******** check for underflow *********/
if ( *count == 0 )
return -1 ;
item = q[ *front ] ;
*front = ( *front + 1 ) % QUE_SIZE ;
*count - = 1 ;
return item ;
}
/*************** display_q ( ) **************/
void display_cq (int front , int count , int q[ ] ) {
register unsigned int i ;
/******** check for underflow *********/
if ( count == 0 ){
printf ( “ Queue is empty!!!” ) ;
return ;
}
/**** display contents of queue ****/
printf ( “\nContents of queue :\n” ) ;
for ( i = 1 ; i <= count ; i++ ) {
printf ( “%d\t” , q [ front ] ) ;
front = ( front + 1 ) % QUE_SIZE ;
}
}
/****** End of Program to implement Circular Queue operations using Dynamic Array *****/

SASA FACILITY MANAGEMENTS Page 51 of 81

You might also like