Implementation of Deque using doubly linked list
Last Updated :
24 Nov, 2023
Deque or Double Ended Queue is a generalized version of Queue data structure that allows insert and delete at both ends. In previous post Implementation of Deque using circular array has been discussed. Now in this post we see how we implement Deque using Doubly Linked List.
Operations on Deque :
Mainly the following four basic operations are performed on queue :
insertFront() : Adds an item at the front of Deque.
insertRear() : Adds an item at the rear of Deque.
deleteFront() : Deletes an item from front of Deque.
deleteRear() : Deletes an item from rear of Deque.
In addition to above operations, following operations are also supported :
getFront() : Gets the front item from queue.
getRear() : Gets the last item from queue.
isEmpty() : Checks whether Deque is empty or not.
size() : Gets number of elements in Deque.
erase() : Deletes all the elements from Deque.
Doubly Linked List Representation of Deque :
For implementing deque, we need to keep track of two pointers, front and rear. We enqueue (push) an item at the rear or the front end of deque and dequeue(pop) an item from both rear and front end.
Working :
Declare two pointers front and rear of type Node, where Node represents the structure of a node of a doubly linked list. Initialize both of them with value NULL.
Insertion at Front end :
1. Allocate space for a newNode of doubly linked list.
2. IF newNode == NULL, then
3. print "Overflow"
4. ELSE
5. IF front == NULL, then
6. rear = front = newNode
7. ELSE
8. newNode->next = front
9. front->prev = newNode
10. front = newNode
Insertion at Rear end :
1. Allocate space for a newNode of doubly linked list.
2. IF newNode == NULL, then
3. print "Overflow"
4. ELSE
5. IF rear == NULL, then
6. front = rear = newNode
7. ELSE
8. newNode->prev = rear
9. rear->next = newNode
10. rear = newNode
Deletion from Front end :
1. IF front == NULL
2. print "Underflow"
3. ELSE
4. Initialize temp = front
5. front = front->next
6. IF front == NULL
7. rear = NULL
8. ELSE
9. front->prev = NULL
10 Deallocate space for temp
Deletion from Rear end :
1. IF front == NULL
2. print "Underflow"
3. ELSE
4. Initialize temp = rear
5. rear = rear->prev
6. IF rear == NULL
7. front = NULL
8. ELSE
9. rear->next = NULL
10 Deallocate space for temp
Implementation:
CPP
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *prev, *next;
static Node* getnode( int data)
{
Node* newNode = (Node*) malloc ( sizeof (Node));
newNode->data = data;
newNode->prev = newNode->next = NULL;
return newNode;
}
};
class Deque {
Node* front;
Node* rear;
int Size;
public :
Deque()
{
front = rear = NULL;
Size = 0;
}
void insertFront( int data);
void insertRear( int data);
void deleteFront();
void deleteRear();
int getFront();
int getRear();
int size();
bool isEmpty();
void erase();
};
bool Deque::isEmpty() { return (front == NULL); }
int Deque::size() { return Size; }
void Deque::insertFront( int data)
{
Node* newNode = Node::getnode(data);
if (newNode == NULL)
cout << "OverFlow\n" ;
else {
if (front == NULL)
rear = front = newNode;
else {
newNode->next = front;
front->prev = newNode;
front = newNode;
}
Size++;
}
}
void Deque::insertRear( int data)
{
Node* newNode = Node::getnode(data);
if (newNode == NULL)
cout << "OverFlow\n" ;
else {
if (rear == NULL)
front = rear = newNode;
else {
newNode->prev = rear;
rear->next = newNode;
rear = newNode;
}
Size++;
}
}
void Deque::deleteFront()
{
if (isEmpty())
cout << "UnderFlow\n" ;
else {
Node* temp = front;
front = front->next;
if (front == NULL)
rear = NULL;
else
front->prev = NULL;
free (temp);
Size--;
}
}
void Deque::deleteRear()
{
if (isEmpty())
cout << "UnderFlow\n" ;
else {
Node* temp = rear;
rear = rear->prev;
if (rear == NULL)
front = NULL;
else
rear->next = NULL;
free (temp);
Size--;
}
}
int Deque::getFront()
{
if (isEmpty())
return -1;
return front->data;
}
int Deque::getRear()
{
if (isEmpty())
return -1;
return rear->data;
}
void Deque::erase()
{
rear = NULL;
while (front != NULL) {
Node* temp = front;
front = front->next;
free (temp);
}
Size = 0;
}
int main()
{
Deque dq;
cout << "Insert element '5' at rear end\n" ;
dq.insertRear(5);
cout << "Insert element '10' at rear end\n" ;
dq.insertRear(10);
cout << "Rear end element: " << dq.getRear() << endl;
dq.deleteRear();
cout << "After deleting rear element new rear"
<< " is: " << dq.getRear() << endl;
cout << "Inserting element '15' at front end \n" ;
dq.insertFront(15);
cout << "Front end element: " << dq.getFront() << endl;
cout << "Number of elements in Deque: " << dq.size()
<< endl;
dq.deleteFront();
cout << "After deleting front element new "
<< "front is: " << dq.getFront() << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
static class Node {
int data;
Node prev, next;
static Node getnode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.prev = newNode.next = null ;
return newNode;
}
};
static class Deque {
Node front;
Node rear;
int Size;
Deque()
{
front = rear = null ;
Size = 0 ;
}
boolean isEmpty() { return (front == null ); }
int size() { return Size; }
void insertFront( int data)
{
Node newNode = Node.getnode(data);
if (newNode == null )
System.out.print( "OverFlow\n" );
else {
if (front == null )
rear = front = newNode;
else {
newNode.next = front;
front.prev = newNode;
front = newNode;
}
Size++;
}
}
void insertRear( int data)
{
Node newNode = Node.getnode(data);
if (newNode == null )
System.out.print( "OverFlow\n" );
else {
if (rear == null )
front = rear = newNode;
else {
newNode.prev = rear;
rear.next = newNode;
rear = newNode;
}
Size++;
}
}
void deleteFront()
{
if (isEmpty())
System.out.print( "UnderFlow\n" );
else {
Node temp = front;
front = front.next;
if (front == null )
rear = null ;
else
front.prev = null ;
Size--;
}
}
void deleteRear()
{
if (isEmpty())
System.out.print( "UnderFlow\n" );
else {
Node temp = rear;
rear = rear.prev;
if (rear == null )
front = null ;
else
rear.next = null ;
Size--;
}
}
int getFront()
{
if (isEmpty())
return - 1 ;
return front.data;
}
int getRear()
{
if (isEmpty())
return - 1 ;
return rear.data;
}
void erase()
{
rear = null ;
while (front != null ) {
Node temp = front;
front = front.next;
}
Size = 0 ;
}
}
public static void main(String[] args)
{
Deque dq = new Deque();
System.out.print(
"Insert element '5' at rear end\n" );
dq.insertRear( 5 );
System.out.print(
"Insert element '10' at rear end\n" );
dq.insertRear( 10 );
System.out.print( "Rear end element: " + dq.getRear()
+ "\n" );
dq.deleteRear();
System.out.print(
"After deleting rear element new rear"
+ " is: " + dq.getRear() + "\n" );
System.out.print(
"Inserting element '15' at front end \n" );
dq.insertFront( 15 );
System.out.print(
"Front end element: " + dq.getFront() + "\n" );
System.out.print( "Number of elements in Deque: "
+ dq.size() + "\n" );
dq.deleteFront();
System.out.print( "After deleting front element new "
+ "front is: " + dq.getFront()
+ "\n" );
}
}
|
Python3
class GFG:
class Node:
data = 0
prev = None
next = None
@staticmethod
def getnode(data):
newNode = GFG.Node()
newNode.data = data
newNode.prev = None
newNode. next = None
return newNode
class Deque:
front = None
rear = None
Size = 0
def __init__( self ):
self .front = None
self .rear = None
self .Size = 0
def isEmpty( self ):
return ( self .front = = None )
def size( self ):
return self .Size
def insertFront( self , data):
newNode = GFG.Node.getnode(data)
if (newNode = = None ):
print ( "OverFlow\n" , end = "")
else :
if ( self .front = = None ):
self .rear = newNode
self .front = newNode
else :
newNode. next = self .front
self .front.prev = newNode
self .front = newNode
self .Size + = 1
def insertRear( self , data):
newNode = GFG.Node.getnode(data)
if (newNode = = None ):
print ( "OverFlow\n" , end = "")
else :
if ( self .rear = = None ):
self .front = newNode
self .rear = newNode
else :
newNode.prev = self .rear
self .rear. next = newNode
self .rear = newNode
self .Size + = 1
def deleteFront( self ):
if ( self .isEmpty()):
print ( "UnderFlow\n" , end = "")
else :
temp = self .front
self .front = self .front. next
if ( self .front = = None ):
self .rear = None
else :
self .front.prev = None
self .Size - = 1
def deleteRear( self ):
if ( self .isEmpty()):
print ( "UnderFlow\n" , end = "")
else :
temp = self .rear
self .rear = self .rear.prev
if ( self .rear = = None ):
self .front = None
else :
self .rear. next = None
self .Size - = 1
def getFront( self ):
if ( self .isEmpty()):
return - 1
return self .front.data
def getRear( self ):
if ( self .isEmpty()):
return - 1
return self .rear.data
def erase( self ):
self .rear = None
while ( self .front ! = None ):
temp = self .front
self .front = self .front. next
self .Size = 0
@staticmethod
def main(args):
dq = GFG.Deque()
print ( "Insert element \'5\' at rear end\n" , end = "")
dq.insertRear( 5 )
print ( "Insert element \'10\' at rear end\n" , end = "")
dq.insertRear( 10 )
print ( "Rear end element: " + str (dq.getRear()) + "\n" , end = "")
dq.deleteRear()
print ( "After deleting rear element new rear" +
" is: " + str (dq.getRear()) + "\n" , end = "")
print ( "Inserting element \'15\' at front end \n" , end = "")
dq.insertFront( 15 )
print ( "Front end element: " + str (dq.getFront()) + "\n" , end = "")
print ( "Number of elements in Deque: " + str (dq.size()) + "\n" , end = "")
dq.deleteFront()
print ( "After deleting front element new " +
"front is: " + str (dq.getFront()) + "\n" , end = "")
if __name__ = = "__main__" :
GFG.main([])
|
C#
using System;
class Deque
{
class Node
{
public int data;
public Node prev, next;
public static Node GetNode( int data)
{
Node newNode = new Node
{
data = data,
prev = null ,
next = null
};
return newNode;
}
}
Node front, rear;
int size;
public Deque()
{
front = rear = null ;
size = 0;
}
public void InsertFront( int data)
{
Node newNode = Node.GetNode(data);
if (newNode == null )
{
Console.WriteLine( "OverFlow" );
}
else
{
if (front == null )
rear = front = newNode;
else
{
newNode.next = front;
front.prev = newNode;
front = newNode;
}
size++;
}
}
public void InsertRear( int data)
{
Node newNode = Node.GetNode(data);
if (newNode == null )
{
Console.WriteLine( "OverFlow" );
}
else
{
if (rear == null )
front = rear = newNode;
else
{
newNode.prev = rear;
rear.next = newNode;
rear = newNode;
}
size++;
}
}
public void DeleteFront()
{
if (IsEmpty())
Console.WriteLine( "UnderFlow" );
else
{
Node temp = front;
front = front.next;
if (front == null )
rear = null ;
else
front.prev = null ;
size--;
Free(temp);
}
}
public void DeleteRear()
{
if (IsEmpty())
Console.WriteLine( "UnderFlow" );
else
{
Node temp = rear;
rear = rear.prev;
if (rear == null )
front = null ;
else
rear.next = null ;
size--;
Free(temp);
}
}
public int GetFront()
{
if (IsEmpty())
return -1;
return front.data;
}
public int GetRear()
{
if (IsEmpty())
return -1;
return rear.data;
}
public int Size()
{
return size;
}
public bool IsEmpty()
{
return (front == null );
}
public void Erase()
{
rear = null ;
while (front != null )
{
Node temp = front;
front = front.next;
Free(temp);
}
size = 0;
}
void Free(Node node)
{
}
}
class Program
{
static void Main()
{
Deque dq = new Deque();
Console.WriteLine( "Insert element '5' at rear end" );
dq.InsertRear(5);
Console.WriteLine( "Insert element '10' at rear end" );
dq.InsertRear(10);
Console.WriteLine( "Rear end element: " + dq.GetRear());
dq.DeleteRear();
Console.WriteLine( "After deleting rear element new rear is: " + dq.GetRear());
Console.WriteLine( "Inserting element '15' at front end" );
dq.InsertFront(15);
Console.WriteLine( "Front end element: " + dq.GetFront());
Console.WriteLine( "Number of elements in Deque: " + dq.Size());
dq.DeleteFront();
Console.WriteLine( "After deleting front element new front is: " + dq.GetFront());
}
}
|
Javascript
class Node {
data = 0;
prev = null ;
next = null ;
static getnode(data) {
const newNode = new Node();
newNode.data = data;
newNode.prev = null ;
newNode.next = null ;
return newNode;
}
}
class Deque {
front = null ;
rear = null ;
size = 0;
constructor() {
this .front = null ;
this .rear = null ;
this .size = 0;
}
isEmpty() {
return this .front === null ;
}
size() {
return this .size;
}
insertFront(data) {
const newNode = Node.getnode(data);
if (newNode === null ) {
console.log( "OverFlow\n" );
} else {
if ( this .front === null ) {
this .rear = newNode;
this .front = newNode;
} else {
newNode.next = this .front;
this .front.prev = newNode;
this .front = newNode;
}
this .size += 1;
}
}
insertRear(data) {
const newNode = Node.getnode(data);
if (newNode === null ) {
console.log( "OverFlow\n" );
} else {
if ( this .rear === null ) {
this .front = newNode;
this .rear = newNode;
} else {
newNode.prev = this .rear;
this .rear.next = newNode;
this .rear = newNode;
}
this .size += 1;
}
}
deleteFront() {
if ( this .isEmpty()) {
console.log( "UnderFlow\n" );
} else {
const temp = this .front;
this .front = this .front.next;
if ( this .front === null ) {
this .rear = null ;
} else {
this .front.prev = null ;
}
this .size -= 1;
}
}
deleteRear() {
if ( this .isEmpty()) {
console.log( "UnderFlow\n" );
} else {
const temp = this .rear;
this .rear = this .rear.prev;
if ( this .rear === null ) {
this .front = null ;
} else {
this .rear.next = null ;
}
this .size -= 1;
}
}
getFront() {
if ( this .isEmpty()) {
return -1;
}
return this .front.data;
}
getRear() {
if ( this .isEmpty()) {
return -1;
}
return this .rear.data;
}
erase() {
this .rear = null ;
while ( this .front !== null ) {
const temp = this .front;
this .front = this .front.next;
}
this .size = 0;
}
}
function main() {
const dq = new Deque();
console.log( "Insert element '5' at rear end" );
dq.insertRear(5);
console.log( "Insert element '10' at rear end" );
dq.insertRear(10);
console.log(`Rear end element: ${dq.getRear()}`);
dq.deleteRear();
console.log(`After deleting rear element new rear is: ${dq.getRear()}`);
console.log( "Inserting element '15' at front end" );
dq.insertFront(15);
console.log(`Front end element: ${dq.getFront()}`);
console.log(`Number of elements in Deque: ${dq.size}`);
dq.deleteFront();
console.log(`After deleting front element new front is: ${dq.getFront()}`);
}
main();
|
Output
Insert element '5' at rear end
Insert element '10' at rear end
Rear end element: 10
After deleting rear element new rear is: 5
Inserting element '15' at front end
Front end element: 15
Number of elements in Deque: 2
After deleting front element new front is: 5
Complexity Analysis:
- Time Complexity : Time complexity of operations like insertFront(), insertRear(), deleteFront(), deleteRear() is O(1). The Time Complexity of erase() is O(n).
- Auxiliary space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...