Implementation of stack using Doubly Linked List
Last Updated :
17 Mar, 2023
Stack and doubly linked lists are two important data structures with their own benefits. Stack is a data structure that follows the LIFO technique and can be implemented using arrays or linked list data structures. Doubly linked list has the advantage that it can also traverse the previous node with the help of “previous” pointer.
Doubly Linked List:
- Doubly Linked list (DLL) is a linked list, which contains nodes that are divided into three parts i.e. Data, next pointer and previous pointers.
- The previous pointer points to the previous node and the next pointer points to the node next to the current node.
- The start pointer points to the first node of the linked list.
The structure of a DLL is shown below.
C++
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
|
Java
static class Node {
int data;
Node next;
Node prev;
}
|
Python3
class node:
def __init__( self ,val):
self .val = val
self .prev = None
self . next = None
|
C#
class Node
{
public int data;
public Node next;
public Node prev;
}
|
Javascript
function Node(data) {
this .data = data;
this .next = null ;
this .prev = null ;
}
|
Stack:
- A stack is a linear data structure in which the elements are accessed through a pointer called the “top” of the stack.
- It follows the LIFO(Last In First Out) technique.
- It can be implemented by array or linked list.
Functions to be Implemented:
Some of the basic functionalities on a stack covered here are:
- push()
- pop()
- isEmpty()
- printstack()
- stacksize()
- topelement()
1. push():
If the stack is empty then take a new node, add data to it and assign “null” to its previous and next pointer as it is the first node of the DLL. Assign top and start as the new node. Otherwise, take a new node, add data to it and assign the “previous” pointer of the new node to the “top” node earlier and next as “null”. Further, update the “top” pointer to hold the value of the new node as that will be the top element of the stack now.
Syntax:
push( d );
Below is the implementation of the method.
C++
void push( int d)
{
struct Node* n;
n = new Node();
n->data = d;
if (isEmpty()) {
n->prev = NULL;
n->next = NULL;
start = n;
top = n;
}
else {
top->next = n;
n->next = NULL;
n->prev = top;
top = n;
}
}
|
Java
void push( int d)
{
Node n = new Node();
n.data = d;
if (n.isEmpty()) {
n.prev = null ;
n.next = null ;
start = n;
top = n;
}
else {
top.next = n;
n.next = null ;
n.prev = top;
top = n;
}
}
|
Python3
def push( self ,element):
newP = node(element)
if self .start = = None :
self .start = self .top = newP
return
newP.prev = self .top
self .top. next = newP
self .top = newP
|
C#
public void Push( int d)
{
Node n = new Node();
n.data = d;
if (n.isEmpty())
{
n.prev = null ;
n.next = null ;
start = n;
top = n;
}
else
{
top.next = n;
n.next = null ;
n.prev = top;
top = n;
}
}
|
Javascript
function push(d) {
var n = new Node();
n.data = d;
if (isEmpty()) {
n.prev = null ;
n.next = null ;
start = n;
top = n;
}
else {
top.next = n;
n.next = null ;
n.prev = top;
top = n;
}
}
|
Time Complexity: O(1)
Auxiliary Space: O(1)
2. pop():
If the stack is empty, then print that stack is empty, Otherwise, assign top ->prev -> next as “null” and assign top as top->prev.
Syntax:
pop();
Below is the implementation of the method.
C++
void pop()
{
struct Node* n;
n = top;
if (isEmpty())
printf ( "Stack is empty" );
else if (top == start) {
top = NULL;
start = NULL;
free (n);
}
else {
top->prev->next = NULL;
top = n->prev;
free (n);
}
}
|
Java
void pop()
{
Node n = top;
if (n.isEmpty())
System.out.println( "Stack is empty" );
else if (top == start) {
top = null ;
start = null ;
}
else {
top.prev.next = null ;
top = n.prev;
}
}
|
Python3
def pop( self ):
if self .isEmpty():
print ( 'List is Empty' )
return
self .top = self .top.prev
if self .top ! = None : self .top. next = None
|
C#
public void pop()
{
Node n ;
n = top;
if (n.isEmpty())
Console.Write( "Stack is empty" );
else if (top == start) {
top = null ;
start = null ;
n = null ;
}
else {
top.prev.next = null ;
top = n.prev;
n = null ;
}
}
|
Javascript
function pop() {
let n;
n = top;
if (isEmpty()) {
console.log( "Stack is empty" );
} else if (top === start) {
top = null ;
start = null ;
free(n);
}
else {
top.prev.next = null ;
top = n.prev;
free(n);
}
}
|
Time Complexity: O(1)
Auxiliary Space: O(1)
3. isEmpty():
Check for the top pointer. If it is “null” then return true. Otherwise, return false.
Syntax:
isEmpty();
Below is the implementation of the method.
C++
bool isEmpty()
{
if (start == NULL)
return true ;
return false ;
}
|
Java
boolean isEmpty()
{
if (start == null )
return true ;
return false ;
}
|
Python3
def isEmpty( self ):
if self .start:
return False
return True
|
C#
public bool IsEmpty()
{
if (start == null )
{
return true ;
}
return false ;
}
|
Javascript
function isEmpty() {
return start == null ;
}
|
Time Complexity: O(1)
Auxiliary Space: O(1)
4. printstack():
If the stack is empty, then print that stack is empty. Otherwise, traverse the doubly linked list from start to end and print the data of each node.
Syntax:
printstack();
Below is the implementation of the method.
C++
void printstack()
{
if (isEmpty())
printf ( "Stack is empty" );
else {
struct Node* ptr = start;
printf ( "Stack is : " );
while (ptr != NULL) {
printf ( "%d " , ptr->data);
ptr = ptr->next;
}
printf ( "\n" );
}
}
|
Java
void printstack()
{
if (isEmpty())
System.out.println( "Stack is empty" );
else {
Node ptr = start;
System.out.println( "Stack is : " );
while (ptr != null ) {
System.out.print(ptr.data + " " );
ptr = ptr.next;
}
System.out.println();
}
}
|
Python3
def printstack( self ):
if self .isEmpty():
print ( 'List is Empty' )
return
curr = self .start
print ( "Stack is : " ,end = '')
while curr ! = None :
print (curr.val,end = ' ' )
curr = curr. next
print ()
|
C#
void PrintStack()
{
if (IsEmpty())
Console.WriteLine( "Stack is empty" );
else {
Node ptr = start;
Console.Write( "Stack is: " );
while (ptr != null ) {
Console.Write(ptr.data + " " );
ptr = ptr.next;
}
Console.WriteLine();
}
}
|
Javascript
function printStack() {
if (isEmpty()) {
console.log( "Stack is empty" );
} else {
let ptr = start;
console.log( "Stack is: " );
while (ptr != null ) {
console.log(ptr.data + " " );
ptr = ptr.next;
}
console.log( "\n" );
}
}
|
Time Complexity: O(N) where N is the size of the stack
Auxiliary Space: O(1)
5. stacksize():
If the stack is empty, then return zero else iterate from the start to end and count the number of nodes of the doubly linked list.
Syntax:
stacksize();
Below is the implementation of the method.
C++
void stacksize()
{
int c = 0;
if (isEmpty())
printf ( "Stack is empty" );
else {
struct Node* ptr = start;
while (ptr != NULL) {
c++;
ptr = ptr->next;
}
}
printf ( " Size of the stack is : %d \n " , c);
}
|
Java
void stacksize()
{
int c = 0 ;
if (isEmpty())
System.out.println( "Stack is empty" );
else {
Node ptr = start;
while (ptr != null ) {
c++;
ptr = ptr.next;
}
}
System.out.println( " Size of the stack is : " + c);
}
|
Python3
def stacksize( self ):
curr = self .start
len = 0
while curr ! = None :
len + = 1
curr = curr. next
print ( "Size of the stack is : " , len )
|
C#
static void stacksize()
{
int c = 0;
if (IsEmpty())
Console.WriteLine( "Stack is empty" );
else
{
Node ptr = start;
while (ptr != null )
{
c++;
ptr = ptr.next;
}
}
Console.WriteLine( "Size of the stack is: {0}" , c);
}
|
Javascript
function stacksize() {
let c = 0;
if (isEmpty()) {
console.log( "Stack is empty" );
} else {
let ptr = start;
while (ptr !== null ) {
c++;
ptr = ptr.next;
}
}
console.log( "Size of the stack is: " + c);
}
|
Time Complexity: O(N) where N is the size of the stack
Auxiliary Space: O(1)
6. topelement():
If the stack is empty, then there is no top element. Otherwise, print the element at the top node of the stack.
Syntax:
topelement();
Below is the implementation of the method.
C++
void topelement()
{
if (isEmpty())
printf ( "Stack is empty" );
else
printf (
"The element at top of the stack is : %d \n" ,
top->data);
}
|
Java
void topelement()
{
if (isEmpty())
System.out.println( "Stack is empty" );
else
System.out.println(
"The element at top of the stack is : " +
top.data);
}
|
Python3
def topelement( self ):
if self .isEmpty():
print ( "Stack is empty" )
else :
print ( "The element at top of the stack is : " , self .top.val)
|
C#
void TopElement()
{
if (IsEmpty())
Console.WriteLine( "Stack is empty" );
else
Console.WriteLine( "The element at top of the stack is : " + top.data);
}
|
Javascript
function topElement() {
if (isEmpty()) {
console.log( "Stack is empty" );
} else {
console.log( "The element at top of the stack is: " + top.data);
}
}
|
Time Complexity: O(1)
Auxiliary Space: O(1)
Implementation of Stack using Doubly Linked List:
Implementation of Stack using Doubly Linked List:
Below is the implementation of the stack using a doubly linked list.
C++
#include <iostream>
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
Node* start = NULL;
Node* top = NULL;
bool isEmpty()
{
if (start == NULL)
return true ;
return false ;
}
void push( int d)
{
struct Node* n;
n = new Node();
n->data = d;
if (isEmpty()) {
n->prev = NULL;
n->next = NULL;
start = n;
top = n;
}
else {
top->next = n;
n->next = NULL;
n->prev = top;
top = n;
}
}
void pop()
{
struct Node* n;
n = top;
if (isEmpty())
printf ( "Stack is empty" );
else if (top == start) {
top = NULL;
start = NULL;
free (n);
}
else {
top->prev->next = NULL;
top = n->prev;
free (n);
}
}
void topelement()
{
if (isEmpty())
printf ( "Stack is empty" );
else
printf (
"The element at top of the stack is : %d \n" ,
top->data);
}
void stacksize()
{
int c = 0;
if (isEmpty())
printf ( "Stack is empty" );
else {
struct Node* ptr = start;
while (ptr != NULL) {
c++;
ptr = ptr->next;
}
}
printf ( "Size of the stack is : %d \n " , c);
}
void printstack()
{
if (isEmpty())
printf ( "Stack is empty" );
else {
struct Node* ptr = start;
printf ( "Stack is : " );
while (ptr != NULL) {
printf ( "%d " , ptr->data);
ptr = ptr->next;
}
printf ( "\n" );
}
}
int main()
{
push(2);
push(5);
push(10);
printstack();
topelement();
stacksize();
pop();
printf ( "\nElement popped from the stack \n" );
topelement();
pop();
printf ( "\nElement popped from the stack \n" );
stacksize();
return 0;
}
|
Java
class GFG {
static class Node {
int data;
Node prev;
Node next;
};
static Node start = null ;
static Node top = null ;
public static boolean isEmpty() {
if (start == null )
return true ;
return false ;
}
public static void push( int d) {
Node n;
n = new Node();
n.data = d;
if (isEmpty()) {
n.prev = null ;
n.next = null ;
start = n;
top = n;
} else {
top.next = n;
n.next = null ;
n.prev = top;
top = n;
}
}
public static void pop() {
Node n;
n = top;
if (isEmpty())
System.out.println( "Stack is empty" );
else if (top == start) {
top = null ;
start = null ;
n = null ;
} else {
top.prev.next = null ;
top = n.prev;
n = null ;
}
}
public static void topelement() {
if (isEmpty())
System.out.println( "Stack is empty" );
else
System.out.println( "The element at top of the stack is : " + top.data);
}
public static void stacksize() {
int c = 0 ;
if (isEmpty())
System.out.println( "Stack is empty" );
else {
Node ptr = start;
while (ptr != null ) {
c++;
ptr = ptr.next;
}
}
System.out.println( "Size of the stack is : " + c);
}
public static void printstack() {
if (isEmpty())
System.out.println( "Stack is empty" );
else {
Node ptr = start;
System.out.print( "Stack is : " );
while (ptr != null ) {
System.out.print(ptr.data + " " );
ptr = ptr.next;
}
System.out.println( "" );
}
}
public static void main(String args[]) {
push( 2 );
push( 5 );
push( 10 );
printstack();
topelement();
stacksize();
pop();
System.out.println( "\nElement popped from the stack " );
topelement();
pop();
System.out.print( "\nElement popped from the stack \n" );
stacksize();
}
}
|
C#
using System;
public class GFG {
class Node {
public int data;
public Node prev;
public Node next;
}
static Node start = null ;
static Node top = null ;
public static bool isEmpty()
{
if (start == null )
return true ;
return false ;
}
public static void push( int d)
{
Node n;
n = new Node();
n.data = d;
if (isEmpty()) {
n.prev = null ;
n.next = null ;
start = n;
top = n;
}
else {
top.next = n;
n.next = null ;
n.prev = top;
top = n;
}
}
public static void pop()
{
Node n;
n = top;
if (isEmpty())
Console.WriteLine( "Stack is empty" );
else if (top == start) {
top = null ;
start = null ;
n = null ;
}
else {
top.prev.next = null ;
top = n.prev;
n = null ;
}
}
public static void topelement()
{
if (isEmpty()) {
Console.WriteLine( "Stack is empty" );
}
else {
Console.WriteLine(
"The element at top of the stack is : "
+ top.data);
}
}
public static void stacksize()
{
int c = 0;
if (isEmpty())
Console.WriteLine( "Stack is empty" );
else {
Node ptr = start;
while (ptr != null ) {
c++;
ptr = ptr.next;
}
}
Console.WriteLine( "Size of the stack is : " + c);
}
public static void printstack()
{
if (isEmpty())
Console.WriteLine( "Stack is empty" );
else {
Node ptr = start;
Console.Write( "Stack is : " );
while (ptr != null ) {
Console.Write(ptr.data + " " );
ptr = ptr.next;
}
Console.WriteLine( "" );
}
}
static public void Main()
{
push(2);
push(5);
push(10);
printstack();
topelement();
stacksize();
pop();
Console.WriteLine(
"\nElement popped from the stack " );
topelement();
pop();
Console.Write( "\nElement popped from the stack \n" );
stacksize();
}
}
|
Python3
class node:
def __init__( self ,val):
self .val = val
self .prev = None
self . next = None
class Stack:
def __init__( self ):
self .start = self .top = None
def isEmpty( self ):
if self .start:
return False
return True
def push( self ,element):
newP = node(element)
if self .start = = None :
self .start = self .top = newP
return
newP.prev = self .top
self .top. next = newP
self .top = newP
def stacksize( self ):
curr = self .start
len = 0
while curr ! = None :
len + = 1
curr = curr. next
print ( "Size of the stack is : " , len )
def pop( self ):
if self .isEmpty():
print ( 'List is Empty' )
return
self .top = self .top.prev
if self .top ! = None : self .top. next = None
def printstack( self ):
if self .isEmpty():
print ( 'List is Empty' )
return
curr = self .start
print ( "Stack is : " ,end = '')
while curr ! = None :
print (curr.val,end = ' ' )
curr = curr. next
print ()
def topelement( self ):
if self .isEmpty():
print ( "Stack is empty" )
else :
print ( "The element at top of the stack is : " , self .top.val)
stack = Stack()
stack.push( 2 )
stack.push( 5 )
stack.push( 10 )
stack.printstack()
stack.topelement()
stack.stacksize()
stack.pop()
print ( "Element popped from the stack " )
stack.topelement()
stack.pop()
print ( "Element popped from the stack" )
stack.stacksize()
|
Javascript
var Node = function (data) {
this .data = data;
this .prev = null ;
this .next = null ;
}
var start = null ;
var top = null ;
function isEmpty() {
if (start == null ) {
return true ;
}
return false ;
}
function push(data) {
var n = new Node(data);
if (isEmpty()) {
n.prev = null ;
n.next = null ;
start = n;
top = n;
}
else {
top.next = n;
n.next = null ;
n.prev = top;
top = n;
}
}
function pop() {
var n = top;
if (isEmpty()) {
console.log( "Stack is empty" );
}
else if (top == start) {
top = null ;
start = null ;
n = null ;
}
else {
top.prev.next = null ;
top = n.prev;
n = null ;
}
}
function topelement() {
if (isEmpty()) {
console.log( "Stack is empty" );
}
else {
console.log( "The element at the top of the stack is: " + top.data);
}
}
function stacksize() {
var c = 0;
if (isEmpty()) {
console.log( "Stack is empty" );
}
else {
var ptr = start;
while (ptr != null ) {
c++;
ptr = ptr.next;
}
}
console.log( "Size of the stack is: " + c);
}
function printstack() {
if (isEmpty()) {
console.log( "Stack is empty" );
}
else {
var ptr = start;
console.log( "Stack is: " );
while (ptr != null ) {
console.log(ptr.data + " " );
ptr = ptr.next;
}
}
}
push(2);
push(5);
push(10);
printstack();
topelement();
stacksize();
pop();
console.log( "Element popped from the stack" );
topelement();
pop();
console.log( "Element popped from the stack" );
stacksize();
function pushIfNotFull(data) {
if (!isFull()) {
push(data);
}
else {
console.log( "Stack is full, cannot push element" );
}
}
function popIfNotEmpty() {
if (!isEmpty()) {
pop();
}
else {
console.log( "Stack is empty, cannot pop element" );
}
}
function clearStack() {
while (!isEmpty()) {
pop();
}
}
|
Output
Stack is : 2 5 10
The element at top of the stack is : 10
Size of the stack is : 3
Element popped from the stack
The element at top of the stack is : 5
Element popped from the stack
Size of the stack is : 1
Complexity Analysis:
Time complexity:
- push(): O(1) as we are not traversing the entire list.
- pop(): O(1) as we are not traversing the entire list.
- isEmpty(): O(1) as we are checking only the head node.
- top_element(): O(1) as we are printing the value of the head node only.
- stack_size(): As we traversed the whole list, it will be O(n), where n is the number of nodes in the linked list.
- print_stack(): As we traversed the whole list, it will be O(n), where n is the number of nodes in the linked list.
Auxiliary Space: O(1), as we require constant extra space.
Share your thoughts in the comments
Please Login to comment...