What is Queue?
A queue is a linear data structure that is open at both ends and the operations are performed in First In First Out (FIFO) order.
We define a queue to be a list in which all additions to the list are made at one end, and all deletions from the list are made at the other end. The element which is first pushed into the order, the delete operation is first performed on that.
- A Queue is like a line waiting to purchase tickets, where the first person in line is the first person served. (i.e. First come first serve).
- Position of the entry in a queue ready to be served, that is, the first entry that will be removed from the queue, is called the front of the queue(sometimes, head of the queue), similarly, the position of the last entry in the queue, that is, the one most recently added, is called the rear (or the tail) of the queue. See the below figure.

FIFO property of queue
Characteristics of Queue:
- Queue can handle multiple data.
- We can access both ends.
- They are fast and flexible.
Queue Representation:
1. Array Representation of Queue:
Like stacks, Queues can also be represented in an array: In this representation, the Queue is implemented using the array. Variables used in this case are
- Queue: the name of the array storing queue elements.
- Front: the index where the first element is stored in the array representing the queue.
- Rear: the index where the last element is stored in an array representing the queue.
Array representation of queue:
C
struct Queue {
int front, rear, size;
unsigned capacity;
int * array;
};
struct Queue* createQueue(unsigned capacity)
{
struct Queue* queue
= ( struct Queue*) malloc ( sizeof ( struct Queue));
queue->capacity = capacity;
queue->front = queue->size = 0;
queue->rear = capacity - 1;
queue->array
= ( int *) malloc (queue->capacity * sizeof ( int ));
return queue;
}
|
C++
class Queue {
public :
int front, rear, size;
unsigned cap;
int * arr;
};
Queue* createQueue(unsigned cap)
{
Queue* queue = new Queue();
queue->cap = cap;
queue->front = queue->size = 0;
queue->rear = cap - 1;
queue->arr = new int [(queue->cap * sizeof ( int ))];
return queue;
}
|
Java
import java.io.*;
class GFG {
static class Queue {
int front, rear, size;
int cap;
int arr[];
}
Queue createQueue( int cap)
{
Queue queue = new Queue();
queue.cap = cap;
queue.front = 0 ;
queue.size = 0 ;
queue.rear = cap - 1 ;
queue.arr = new int [queue.cap];
return queue;
}
}
|
Python3
class Queue:
def __init__( self , cap):
self .cap = cap
self .front = 0
self .size = 0
self .rear = cap - 1
self .arr = [ 0 ] * cap
def createQueue( self ):
return Queue( self .cap)
|
C#
class GFG {
static class Queue {
public int front, rear, size;
public int cap;
public int [] arr;
}
public static Queue createQueue( int cap)
{
Queue queue = new Queue();
queue.cap = cap;
queue.front = 0;
queue.size = 0;
queue.rear = cap - 1;
queue.arr = new int [queue.cap];
return queue;
}
}
|
Javascript
<script>
class Queue
{
constructor()
{
this .items = [];
}
}
<script>
|
2. Linked List Representation of Queue:
A queue can also be represented using following entities:
- Linked-lists,
- Pointers, and
- Structures.
C
struct QNode {
int key;
struct QNode* next;
};
struct Queue {
struct QNode *front, *rear;
};
struct QNode* newNode( int k)
{
struct QNode* temp
= ( struct QNode*) malloc ( sizeof ( struct QNode));
temp->key = k;
temp->next = NULL;
return temp;
}
struct Queue* createQueue()
{
struct Queue* q
= ( struct Queue*) malloc ( sizeof ( struct Queue));
q->front = q->rear = NULL;
return q;
}
|
C++
struct QNode {
int data;
QNode* next;
QNode( int d)
{
data = d;
next = NULL;
}
};
struct Queue {
QNode *front, *rear;
Queue() { front = rear = NULL; }
};
|
Java
import java.io.*;
class GFG {
static class QNode {
int data;
QNode next;
QNode( int data)
{
this .data = data;
next = null ;
}
}
static class Queue {
QNode front, rear;
Queue()
{
front = null ;
rear = null ;
}
}
}
|
Python3
class QNode:
def __init__( self , data):
self .data = data
self . next = None
class Queue:
def __init__( self ):
self .front = None
self .rear = None
|
C#
using System;
public class GFG {
static class QNode {
public int data;
public QNode next;
public QNode( int data)
{
this .data = data;
this .next = null ;
}
}
static class Queue {
public QNode front;
public QNode rear;
public Queue()
{
this .front = null ;
this .rear = null ;
}
}
}
|
Javascript
<script>
class QNode
{
constructor(key)
{
this .key = key;
this .next = null ;
}
}
let front = null , rear = null ;
<script>
|
There are different types of queues:
- Input Restricted Queue: This is a simple queue. In this type of queue, the input can be taken from only one end but deletion can be done from any of the ends.
- Output Restricted Queue: This is also a simple queue. In this type of queue, the input can be taken from both ends but deletion can be done from only one end.
- Circular Queue: This is a special type of queue where the last position is connected back to the first position. Here also the operations are performed in FIFO order. To know more refer this.
- Double-Ended Queue (Dequeue): In a double-ended queue the insertion and deletion operations, both can be performed from both ends. To know more refer this.
- Priority Queue: A priority queue is a special queue where the elements are accessed based on the priority assigned to them. To know more refer this.
To learn more about different types of queues, read the article on “Types of Queues“.
Basic Operations for Queue in Data Structure:
Some of the basic operations for Queue in Data Structure are:
- Enqueue() – Adds (or stores) an element to the end of the queue..
- Dequeue() – Removal of elements from the queue.
- Peek() or front()- Acquires the data element available at the front node of the queue without deleting it.
- rear() – This operation returns the element at the rear end without removing it.
- isFull() – Validates if the queue is full.
- isNull() – Checks if the queue is empty.
There are a few supporting operations (auxiliary operations):
1. Enqueue():
Enqueue() operation in Queue adds (or stores) an element to the end of the queue.
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, return overflow error and exit.
- Step 3: If the queue is not full, increment the rear pointer to point to the next empty space.
- Step 4: Add the data element to the queue location, where the rear is pointing.
- Step 5: return success.

Enqueue representation
Implementation of Enqueue:
C
void enqueue( struct Queue* queue, int item)
{
if (isFull(queue))
return ;
queue->rear = (queue->rear + 1) % queue->capacity;
queue->array[queue->rear] = item;
queue->size = queue->size + 1;
printf ( "%d enqueued to queue\n" , item);
}
|
C++
void queueEnqueue( int data)
{
if (capacity == rear) {
printf ( "\nQueue is full\n" );
return ;
}
else {
queue[rear] = data;
rear++;
}
return ;
}
|
Java
void queueEnqueue( int data)
{
if (capacity == rear) {
System.out.println( "\nQueue is full\n" );
return ;
}
else {
queue[rear] = data;
rear++;
}
return ;
}
|
Python3
def EnQueue( self , item):
if self .isFull():
print ( "Full" )
return
self .rear = ( self .rear + 1 ) % ( self .capacity)
self .Q[ self .rear] = item
self .size = self .size + 1
print ( "% s enqueued to queue" % str (item))
|
C#
public void enqueue( int item)
{
if (rear == max - 1) {
Console.WriteLine( "Queue Overflow" );
return ;
}
else {
ele[++rear] = item;
}
}
|
Javascript
<script>
enqueue(element){
this .items.push(element);
}
</script>
|
2. Dequeue():
Removes (or access) the first element from the queue.
The following steps are taken to perform the dequeue operation:
- Step 1: Check if the queue is empty.
- Step 2: If the queue is empty, return the underflow error and exit.
- Step 3: If the queue is not empty, access the data where the front is pointing.
- Step 4: Increment the front pointer to point to the next available data element.
- Step 5: The Return success.

Dequeue operation
Implementation of dequeue:
C
int dequeue( struct Queue* queue)
{
if (isEmpty(queue)) {
printf ( "\nQueue is empty\n" );
return ;
}
int item = queue->array[queue->front];
queue->front = (queue->front + 1) % queue->capacity;
queue->size = queue->size - 1;
return item;
}
|
C++
void queueDequeue()
{
if (front == rear) {
printf ( "\nQueue is empty\n" );
return ;
}
else {
for ( int i = 0; i < rear - 1; i++) {
queue[i] = queue[i + 1];
}
rear--;
}
return ;
}
|
Java
void queueDequeue()
{
if (front == rear) {
System.out.println( "\nQueue is empty\n" );
return ;
}
else {
for ( int i = 0 ; i < rear - 1 ; i++) {
queue[i] = queue[i + 1 ];
}
rear--;
}
return ;
}
|
Python3
def DeQueue( self ):
if self .isEmpty():
print ( "Queue is empty" )
return
print ( "% s dequeued from queue" % str ( self .Q[ self .front]))
self .front = ( self .front + 1 ) % ( self .capacity)
self .size = self .size - 1
|
C#
public int dequeue()
{
if (front == rear + 1) {
Console.WriteLine( "Queue is Empty" );
return -1;
}
else {
int p = ele[front++];
return p;
}
}
|
Javascript
<script>
dequeue(){
if ( this .isEmpty()){
document.write( "<br>Queue is empty<br>" );
return -1;
}
return this .items.shift();
}
</script>
|
3. front():
This operation returns the element at the front end without removing it.
C
int front( struct Queue* queue)
{
if (isempty(queue))
return INT_MIN;
return queue->arr[queue->front];
}
|
C++
int front(Queue* queue)
{
if (isempty(queue))
return INT_MIN;
return queue->arr[queue->front];
}
|
Java
int front(Queue queue)
{
if (isempty(queue))
return Integer.MIN_VALUE;
return queue.arr[queue.front];
}
|
Python3
def que_front( self ):
if self .isempty():
return "Queue is empty"
return self .Q[ self .front]
|
C#
public int front()
{
if (isempty())
return INT_MIN;
return arr[front];
}
|
Javascript
<script>
front(){
if ( this .isEmpty())
return "No elements in Queue<br>" ;
return this .items[0];
}
<script>
|
4. rear():
This operation returns the element at the rear end without removing it.
C
int rear( struct Queue* front)
{
if (front == NULL) {
printf ( "Queue is empty.\n" );
return -1;
}
while (front->next != NULL) {
front = front->next;
}
return front->data;
}
|
C++
int rear(queue< int >& myQueue)
{
queue< int > tempQueue = myQueue;
while (tempQueue.size() > 1) {
tempQueue.pop();
}
return tempQueue.front();
}
|
Java
public static int rear(Queue<Integer> myQueue)
{
if (myQueue.isEmpty()) {
System.out.println( "Queue is empty." );
return - 1 ;
}
int rearElement = - 1 ;
while (!myQueue.isEmpty()) {
rearElement = myQueue.poll();
}
return rearElement;
}
|
Python3
def rear(queue):
if queue.empty():
print ( "Queue is empty." )
return None
rear_element = None
while not queue.empty():
rear_element = queue.get()
return rear_element
|
C#
static int Rear(Queue< int > myQueue)
{
if (myQueue.Count == 0) {
Console.WriteLine( "Queue is empty." );
return -1;
}
int rearElement = -1;
while (myQueue.Count > 0) {
rearElement = myQueue.Dequeue();
}
return rearElement;
}
|
Javascript
function rear(queue) {
if (queue.length === 0) {
console.log( "Queue is empty." );
return -1;
}
let rearElement = -1;
while (queue.length > 0) {
rearElement = queue.shift();
}
return rearElement;
}
|
5. isEmpty():
This operation returns a boolean value that indicates whether the queue is empty or not.
C
bool isEmpty( struct Queue* queue)
{
return (queue->size == 0);
}
|
C++
bool isEmpty()
{
if (front == -1)
return true ;
else
return false ;
}
|
Java
boolean isEmpty()
{
if (front == - 1 )
return true ;
else
return false ;
}
|
Python3
def isEmpty( self ):
return self .size = = 0
|
C#
bool isEmpty()
{
if (front == -1)
return true ;
else
return false ;
}
|
Javascript
</script>
isEmpty(){
return this .items.length == 0;
}
</script>
|
6. isFull():
This operation returns a boolean value that indicates whether the queue is full or not.
C
bool isFull( struct Queue* queue)
{
return (queue->size == queue->capacity);
}
|
C++
bool isFull()
{
if (front == 0 && rear == MAX_SIZE - 1) {
return true ;
}
return false ;
}
|
Java
boolean isFull()
{
if (front == 0 && rear == MAX_SIZE - 1 ) {
return true ;
}
return false ;
}
|
Python3
def isFull( self ):
return self .size = = self .capacity
|
C#
public bool isFull( int item) { return (rear == max - 1); }
|
Javascript
function isFull(){
if (front==0 && rear==MAX_SIZE-1){
return true ;
}
return false ;
}
|
Implementation of Queue:
Queue can be implemented using following data structures:
We have discussed the Structure implementation of Queue below:
C
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
struct Queue {
int front, rear, size;
unsigned capacity;
int * array;
};
struct Queue* createQueue(unsigned capacity)
{
struct Queue* queue
= ( struct Queue*) malloc ( sizeof ( struct Queue));
queue->capacity = capacity;
queue->front = queue->size = 0;
queue->rear = capacity - 1;
queue->array
= ( int *) malloc (queue->capacity * sizeof ( int ));
return queue;
}
int isFull( struct Queue* queue)
{
return (queue->size == queue->capacity);
}
int isEmpty( struct Queue* queue)
{
return (queue->size == 0);
}
void enqueue( struct Queue* queue, int item)
{
if (isFull(queue))
return ;
queue->rear = (queue->rear + 1) % queue->capacity;
queue->array[queue->rear] = item;
queue->size = queue->size + 1;
printf ( "%d enqueued to queue\n" , item);
}
int dequeue( struct Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
int item = queue->array[queue->front];
queue->front = (queue->front + 1) % queue->capacity;
queue->size = queue->size - 1;
return item;
}
int front( struct Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
return queue->array[queue->front];
}
int rear( struct Queue* queue)
{
if (isEmpty(queue))
return INT_MIN;
return queue->array[queue->rear];
}
int main()
{
struct Queue* queue = createQueue(1000);
enqueue(queue, 10);
enqueue(queue, 20);
enqueue(queue, 30);
enqueue(queue, 40);
printf ( "%d dequeued from queue\n" , dequeue(queue));
printf ( "Front item is %d\n" , front(queue));
printf ( "Rear item is %d\n" , rear(queue));
return 0;
}
|
C++
#include <bits/stdc++.h>
using namespace std;
class Queue {
public :
int front, rear, size;
unsigned cap;
int * arr;
};
Queue* createQueue(unsigned cap)
{
Queue* queue = new Queue();
queue->cap = cap;
queue->front = queue->size = 0;
queue->rear = cap - 1;
queue->arr = new int [(queue->cap * sizeof ( int ))];
return queue;
}
int isFull(Queue* queue)
{
return (queue->size == queue->cap);
}
int isempty(Queue* queue) { return (queue->size == 0); }
void enqueue(Queue* queue, int item)
{
if (isFull(queue))
return ;
queue->rear = (queue->rear + 1) % queue->cap;
queue->arr[queue->rear] = item;
queue->size = queue->size + 1;
cout << item << " enqueued to queue\n" ;
}
int dequeue(Queue* queue)
{
if (isempty(queue))
return INT_MIN;
int item = queue->arr[queue->front];
queue->front = (queue->front + 1) % queue->cap;
queue->size = queue->size - 1;
return item;
}
int front(Queue* queue)
{
if (isempty(queue))
return INT_MIN;
return queue->arr[queue->front];
}
int rear(Queue* queue)
{
if (isempty(queue))
return INT_MIN;
return queue->arr[queue->rear];
}
int main()
{
Queue* queue = createQueue(1000);
enqueue(queue, 10);
enqueue(queue, 20);
enqueue(queue, 30);
enqueue(queue, 40);
cout << dequeue(queue);
cout << " dequeued from queue\n" ;
cout << "Front item is " << front(queue) << endl;
cout << "Rear item is " << rear(queue);
return 0;
}
|
Java
class Queue {
int front, rear, size;
int capacity;
int array[];
public Queue( int capacity)
{
this .capacity = capacity;
front = this .size = 0 ;
rear = capacity - 1 ;
array = new int [ this .capacity];
}
boolean isFull(Queue queue)
{
return (queue.size == queue.capacity);
}
boolean isEmpty(Queue queue)
{
return (queue.size == 0 );
}
void enqueue( int item)
{
if (isFull( this ))
return ;
this .rear = ( this .rear + 1 ) % this .capacity;
this .array[ this .rear] = item;
this .size = this .size + 1 ;
System.out.println(item + " enqueued to queue" );
}
int dequeue()
{
if (isEmpty( this ))
return Integer.MIN_VALUE;
int item = this .array[ this .front];
this .front = ( this .front + 1 ) % this .capacity;
this .size = this .size - 1 ;
return item;
}
int front()
{
if (isEmpty( this ))
return Integer.MIN_VALUE;
return this .array[ this .front];
}
int rear()
{
if (isEmpty( this ))
return Integer.MIN_VALUE;
return this .array[ this .rear];
}
}
public class Test {
public static void main(String[] args)
{
Queue queue = new Queue( 1000 );
queue.enqueue( 10 );
queue.enqueue( 20 );
queue.enqueue( 30 );
queue.enqueue( 40 );
System.out.println(queue.dequeue()
+ " dequeued from queue" );
System.out.println( "Front item is "
+ queue.front());
System.out.println( "Rear item is " + queue.rear());
}
}
|
Python3
class Queue:
def __init__( self , capacity):
self .front = self .size = 0
self .rear = capacity - 1
self .Q = [ None ] * capacity
self .capacity = capacity
def isFull( self ):
return self .size = = self .capacity
def isEmpty( self ):
return self .size = = 0
def EnQueue( self , item):
if self .isFull():
print ( "Full" )
return
self .rear = ( self .rear + 1 ) % ( self .capacity)
self .Q[ self .rear] = item
self .size = self .size + 1
print ( "% s enqueued to queue" % str (item))
def DeQueue( self ):
if self .isEmpty():
print ( "Empty" )
return
print ( "% s dequeued from queue" % str ( self .Q[ self .front]))
self .front = ( self .front + 1 ) % ( self .capacity)
self .size = self .size - 1
def que_front( self ):
if self .isEmpty():
print ( "Queue is empty" )
print ( "Front item is" , self .Q[ self .front])
def que_rear( self ):
if self .isEmpty():
print ( "Queue is empty" )
print ( "Rear item is" , self .Q[ self .rear])
if __name__ = = '__main__' :
queue = Queue( 30 )
queue.EnQueue( 10 )
queue.EnQueue( 20 )
queue.EnQueue( 30 )
queue.EnQueue( 40 )
queue.DeQueue()
queue.que_front()
queue.que_rear()
|
C#
using System;
namespace GeeksForGeeks {
class Queue {
private int [] ele;
private int front;
private int rear;
private int max;
public Queue( int size)
{
ele = new int [size];
front = 0;
rear = -1;
max = size;
}
public void enqueue( int item)
{
if (rear == max - 1) {
Console.WriteLine( "Queue Overflow" );
return ;
}
else {
ele[++rear] = item;
}
}
public int dequeue()
{
if (front == rear + 1) {
Console.WriteLine( "Queue is Empty" );
return -1;
}
else {
Console.WriteLine(ele[front]
+ " dequeued from queue" );
int p = ele[front++];
Console.WriteLine( "Front item is {0}" ,
ele[front]);
Console.WriteLine( "Rear item is {0} " ,
ele[rear]);
return p;
}
}
public void printQueue()
{
if (front == rear + 1) {
Console.WriteLine( "Queue is Empty" );
return ;
}
else {
for ( int i = front; i <= rear; i++) {
Console.WriteLine(ele[i]
+ " enqueued to queue" );
}
}
}
}
class Program {
static void Main()
{
Queue Q = new Queue(5);
Q.enqueue(10);
Q.enqueue(20);
Q.enqueue(30);
Q.enqueue(40);
Q.printQueue();
Q.dequeue();
}
}
}
|
Javascript
<script>
class Queue
{
constructor()
{
this .items = [];
}
isEmpty()
{
return this .items.length == 0;
}
enqueue(element)
{
this .items.push(element);
document.write(element + " enqueued to queue<br>" );
}
dequeue()
{
if ( this .isEmpty())
return "Underflow<br>" ;
return this .items.shift();
}
front()
{
if ( this .isEmpty())
return "No elements in Queue<br>" ;
return this .items[0];
}
rear()
{
if ( this .isEmpty())
return "No elements in Queue<br>" ;
return this .items[ this .items.length-1];
}
}
var queue = new Queue();
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
queue.enqueue(40);
document.write(queue.dequeue() + " dequeued from queue<br>" );
document.write( "Front item is " + queue.front() + "<br>" );
document.write( "Rear item is " + queue.rear() + "<br>" );
</script>
|
Output
10 enqueued to queue
20 enqueued to queue
30 enqueued to queue
40 enqueued to queue
10 dequeued from queue
Front item is 20
Rear item is 40
Time complexity: All the operations have O(1) time complexity.
Auxiliary Space: O(N)
Application of queue is common. In a computer system, there may be queues of tasks waiting for the printer, for access to disk storage, or even in a time-sharing system, for use of the CPU. Within a single program, there may be multiple requests to be kept in a queue, or one task may create other tasks, which must be done in turn by keeping them in a queue.
- It has a single resource and multiple consumers.
- It synchronizes between slow and fast devices.
- In a network, a queue is used in devices such as a router/switch and mail queue.
- Variations: dequeue, priority queue and double-ended priority queue.
FAQs (Frequently asked questions) on Queue:
1. What data structure can be used to implement a priority queue?
Priority queues can be implemented using a variety of data structures, including linked lists, arrays, binary search trees, and heaps. Priority queues are best implemented using the heap data structure.
2. Queues are used for what purpose?
In addition to making your data persistent, queues reduce errors that occur when different parts of your system are down.
3. In data structures, what is a double-ended queue?
In a double-ended queue, elements can be inserted and removed at both ends.
4. What is better, a stack or a queue?
If you want things to come out in the order you put them in, use a queue. Stacks are useful when you want to reorder things after putting them in.
Related articles:
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
24 May, 2023
Like Article
Save Article