Name some Queue implementations and compare them by efficiency of operations
Last Updated :
30 Mar, 2023
A queue is a linear data structure in which insertion is done from one end called the rear end and deletion is done from another end called the front end. It follows FIFO (First In First Out) approach. The insertion in the queue is called enqueue operation and deletion in the queue is called dequeue operation.
A queue can be implemented in two ways:
- Array implementation of queue
- Linked List implementation of queue
Array implementation of the queue:
For the array implementation of the queue, we have to take an array of size n. We also use two pointers front and rear to keep track of the front element and the last position where a new element can be inserted respectively. All the functionalities are satisfied by using these two pointers. For more details about array implementation of a queue refer to this link.
Below is the code for array implementation of a queue.
C++
#include <bits/stdc++.h>
using namespace std;
struct Queue {
int rear, front, s;
int * q;
Queue( int c)
{
front = rear = 0;
s = c;
q = new int ;
}
~Queue() { delete [] q; }
void enqueue( int data)
{
if (rear == s)
cout << "Queue is full\n" ;
else {
q[rear] = data;
rear++;
}
return ;
}
void dequeue()
{
if (rear == front)
cout << "Queue is empty\n" ;
else
front++;
}
void display()
{
if (rear == front)
cout << "Queue is empty\n" ;
else
for ( int i = front; i < rear; i++) {
cout << q[i] << " " ;
}
}
};
int main()
{
Queue p(3);
p.enqueue(10);
p.enqueue(20);
p.enqueue(30);
p.display();
cout << "\nAfter two deletion\n" ;
p.dequeue();
p.dequeue();
p.display();
return 0;
}
|
Java
import java.io.*;
class GFG {
static class Queue {
int rear, front, s;
int q[];
Queue( int c)
{
front = 0 ;
rear = 0 ;
s = c;
q = new int [s];
}
void enqueue( int data)
{
if (rear == s)
System.out.println( "Queue is full" );
else {
q[rear] = data;
rear++;
}
return ;
}
void dequeue()
{
if (rear == front)
System.out.println( "Queue is empty" );
else
front++;
}
void display()
{
if (rear == front)
System.out.println( "Queue is empty" );
else
for ( int i = front; i < rear; i++) {
System.out.print(q[i]+ " " );
}
}
}
public static void main (String[] args) {
Queue p = new Queue( 3 );
p.enqueue( 10 );
p.enqueue( 20 );
p.enqueue( 30 );
p.display();
System.out.println( "\nAfter two deletion" );
p.dequeue();
p.dequeue();
p.display();
}
}
|
Python3
class Queue:
def __init__( self , c):
self .rear = 0
self .front = 0
self .s = c
self .q = [ 0 ] * c
def enqueue( self , data):
if self .rear = = self .s:
print ( "Queue is full" )
else :
self .q[ self .rear] = data
self .rear + = 1
def dequeue( self ):
if self .rear = = self .front:
print ( "Queue is empty" )
else :
self .front + = 1
def display( self ):
if self .rear = = self .front:
print ( "Queue is empty" )
else :
for i in range ( self .front, self .rear):
print ( self .q[i], end = " " )
print ()
if __name__ = = "__main__" :
p = Queue( 3 )
p.enqueue( 10 )
p.enqueue( 20 )
p.enqueue( 30 )
p.display()
print ( "After two deletion" )
p.dequeue()
p.dequeue()
p.display()
|
C#
using System;
public class GFG {
class Queue {
public int rear, front, s;
public int [] q;
public Queue( int c)
{
front = 0;
rear = 0;
s = c;
q = new int [s];
}
public void enqueue( int data)
{
if (rear == s)
Console.WriteLine( "Queue is full" );
else {
q[rear] = data;
rear++;
}
return ;
}
public void dequeue()
{
if (rear == front)
Console.WriteLine( "Queue is empty" );
else
front++;
}
public void display()
{
if (rear == front)
Console.WriteLine( "Queue is empty" );
else
for ( int i = front; i < rear; i++) {
Console.Write(q[i] + " " );
}
}
}
static public void Main()
{
Queue p = new Queue(3);
p.enqueue(10);
p.enqueue(20);
p.enqueue(30);
p.display();
Console.WriteLine( "\nAfter two deletion" );
p.dequeue();
p.dequeue();
p.display();
}
}
|
Javascript
class Queue {
constructor() {
this .rear = 0;
this .front = 0;
this .q = new Array;
}
enqueue(data) {
if ( this .rear == 3)
console.log( "Queue is full" );
else {
this .q[ this .rear] = data;
this .rear++;
}
return ;
}
dequeue() {
if ( this .rear == this .front)
console.log( "Queue is empty" );
else
this .front++;
}
display() {
if ( this .rear == this .front)
console.log( "Queue is empty" );
else
for (let i = this .front; i < this .rear; i++) {
console.log( this .q[i], " " );
}
}
};
let p = new Queue;
p.enqueue(10);
p.enqueue(20);
p.enqueue(30);
p.display();
console.log( "After two deletion" );
p.dequeue();
p.dequeue();
p.display();
|
Output
10 20 30
After two deletion
30
Time Complexity:
Insertion: O(1)
Deletion: O(1)
Searching: O(n)
Space Complexity: O(n)
Linked List Implementation of the queue:
For implementing a queue using linked list we don’t need to know the size beforehand like array. The dynamic property of linked list allows queue to grow to any size. In case of a linked list also we use two pointers front and rear that perform the same task as in array. For more details about linked list implementation refer to this link.
Below is the code for linked list implementation of queue.
C++
#include <bits/stdc++.h>
using namespace std;
struct Qnode {
int d;
struct Qnode* next;
};
struct Q {
struct Qnode *front, *rear;
};
struct Qnode* newNode( int k)
{
struct Qnode* t
= ( struct Qnode*) malloc ( sizeof ( struct Qnode));
t->d = k;
t->next = NULL;
return t;
}
struct Q* createQ()
{
struct Q* q = ( struct Q*) malloc ( sizeof ( struct Q));
q->front = q->rear = NULL;
return q;
}
void enqueue( struct Q* q, int data)
{
struct Qnode* t = newNode(data);
if (q->rear == NULL) {
q->front = q->rear = t;
return ;
}
q->rear->next = t;
q->rear = t;
}
void dequeue( struct Q* q)
{
if (q->front == NULL)
return ;
struct Qnode* t = q->front;
q->front = q->front->next;
if (q->front == NULL)
q->rear = NULL;
free (t);
}
int main()
{
struct Q* q = createQ();
enqueue(q, 10);
enqueue(q, 20);
enqueue(q, 30);
dequeue(q);
cout << "Queue front " << q->front->d;
cout << "\nQueue rear " << q->rear->d;
return 0;
}
|
Java
class Qnode {
int d;
Qnode next;
}
class Q {
Qnode front, rear;
Q() {
front = rear = null ;
}
}
class Main {
static Qnode newNode( int k) {
Qnode t = new Qnode();
t.d = k;
t.next = null ;
return t;
}
static Q createQ() {
Q q = new Q();
return q;
}
static void enqueue(Q q, int data) {
Qnode t = newNode(data);
if (q.rear == null ) {
q.front = q.rear = t;
return ;
}
q.rear.next = t;
q.rear = t;
}
static void dequeue(Q q) {
if (q.front == null ) {
return ;
}
Qnode t = q.front;
q.front = q.front.next;
if (q.front == null ) {
q.rear = null ;
}
t = null ;
}
public static void main(String[] args) {
Q q = createQ();
enqueue(q, 10 );
enqueue(q, 20 );
enqueue(q, 30 );
dequeue(q);
System.out.println( "Queue front: " + q.front.d);
System.out.println( "Queue rear: " + q.rear.d);
}
}
|
Python
class Qnode:
def __init__( self , d):
self .d = d
self . next = None
class Q:
def __init__( self ):
self .front = None
self .rear = None
def newNode(k):
t = Qnode(k)
return t
def createQ():
q = Q()
return q
def enqueue(q, data):
t = newNode(data)
if q.rear is None :
q.front = q.rear = t
return
q.rear. next = t
q.rear = t
def dequeue(q):
if q.front is None :
return
t = q.front
q.front = q.front. next
if q.front is None :
q.rear = None
t = None
q = createQ()
enqueue(q, 10 )
enqueue(q, 20 )
enqueue(q, 30 )
dequeue(q)
print ( "Queue front: " , q.front.d)
print ( "Queue rear: " , q.rear.d)
|
C#
public class Qnode
{
public int d;
public Qnode next;
public Qnode( int val)
{
d = val;
next = null ;
}
}
public class Q
{
public Qnode front, rear;
public Q()
{
front = rear = null ;
}
}
public class MainClass
{
public static Qnode newNode( int k)
{
Qnode t = new Qnode(k);
return t;
}
public static Q createQ()
{
Q q = new Q();
return q;
}
public static void enqueue(Q q, int data)
{
Qnode t = newNode(data);
if (q.rear == null )
{
q.front = q.rear = t;
return ;
}
q.rear.next = t;
q.rear = t;
}
public static void dequeue(Q q)
{
if (q.front == null )
{
return ;
}
Qnode t = q.front;
q.front = q.front.next;
if (q.front == null )
{
q.rear = null ;
}
t = null ;
}
public static void Main( string [] args)
{
Q q = createQ();
enqueue(q, 10);
enqueue(q, 20);
enqueue(q, 30);
dequeue(q);
System.Console.WriteLine( "Queue front: " + q.front.d);
System.Console.WriteLine( "Queue rear: " + q.rear.d);
}
}
|
Javascript
class QNode {
constructor(data) {
this .d = data;
this .next = null ;
}
}
class Q {
constructor() {
this .front = this .rear = null ;
}
}
const newNode = data => new QNode(data);
const createQ = () => new Q();
const enqueue = (q, data) => {
const t = newNode(data);
if (q.rear === null ) {
q.front = q.rear = t;
return ;
}
q.rear.next = t;
q.rear = t;
};
const dequeue = q => {
if (q.front === null ) return ;
const t = q.front;
q.front = q.front.next;
if (q.front === null ) q.rear = null ;
};
const q = createQ();
enqueue(q, 10);
enqueue(q, 20);
enqueue(q, 30);
dequeue(q);
console.log( "Queue front: " , q.front.d);
console.log( "Queue rear: " , q.rear.d);
|
Output
Queue front 20
Queue rear 30
Time complexity: The time complexity of enqueue and dequeue operations in a queue implemented using linked list is O(1). This is because, in a linked list, insertion and deletion operations are performed in constant time.
Space complexity: The space complexity of a queue implemented using linked list is O(n), where n is the number of elements in the queue. This is because we need to allocate memory for each element in the queue and the size of the queue increases or decreases as elements are added or removed.
Note: For easy understanding only the enqueue() and deque() functionalities are shown here. For detailed implementation you can check the links provided for implementation.
Comparison:
Queue Operations |
Array Implementation |
Linked-List Implementation |
Time Complexity |
Space Complexity |
Time Complexity |
Space Complexity |
Enqueue |
O (1) |
O (1) |
O (1) |
O (1) |
Dequeue |
O (1) |
O (1) |
O (1) |
O (1) |
IsFull |
O (1) |
O (1) |
O (N) |
O (1) |
IsEmpty |
O (1) |
O (1) |
O (1) |
O (1) |
Peek |
O (1) |
O (1) |
O (1) |
O (1) |
Related articles:
Share your thoughts in the comments
Please Login to comment...