Open In App

Implementation of stack using Doubly Linked List

Last Updated : 17 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// Declaration of Doubly Linked List
struct Node {
    int data;
    struct Node* next;
    struct Node* prev;
};


Java




// Declaration of Doubly Linked List
static class Node {
    int data;
    Node next;
    Node prev;
}


Python3




# Declaration of Doubly Linked List
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:

  1. push()
  2. pop() 
  3. isEmpty()
  4. printstack()
  5. stacksize()
  6. 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;
 
        // As it is first node
        // if stack is empty
        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;
 
        // As it is first node
        // if stack is empty
        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;
 
        // As it is first node
        // if stack is empty
        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;
}
// This code is contributed by akashish__


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();
    }
}
 
// This code is contributed by akashish__


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++




// A complete working program to
// demonstrate all stack operations using
// a doubly linked list
 
#include <iostream>
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};
Node* start = NULL;
Node* top = NULL;
 
// Check if stack is empty
bool isEmpty()
{
    if (start == NULL)
        return true;
    return false;
}
 
// pushes element onto stack
void push(int d)
{
    struct Node* n;
    n = new Node();
    n->data = d;
    if (isEmpty()) {
        n->prev = NULL;
        n->next = NULL;
 
        // As it is first node if stack
        // is empty
        start = n;
        top = n;
    }
    else {
        top->next = n;
        n->next = NULL;
        n->prev = top;
        top = n;
    }
}
 
// Pops top element from stack
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);
    }
}
 
// Prints top element of the stack
void topelement()
{
    if (isEmpty())
        printf("Stack is empty");
    else
        printf(
            "The element at top of the stack is : %d   \n",
            top->data);
}
 
// Determines the size of the stack
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);
}
 
// Determines the size of the stack
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");
    }
}
 
// Driver code
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




// A complete working java program to
// demonstrate all stack operations using
// a doubly linked list
 
class GFG {
 
  static class Node {
    int data;
    Node prev;
    Node next;
  };
 
  static Node start = null;
  static Node top = null;
 
  // Check if stack is empty
  public static boolean isEmpty() {
    if (start == null)
      return true;
    return false;
  }
 
  // pushes element onto stack
  public static void push(int d) {
    Node n;
    n = new Node();
    n.data = d;
    if (isEmpty()) {
      n.prev = null;
      n.next = null;
 
      // As it is first node if stack
      // is empty
      start = n;
      top = n;
    } else {
      top.next = n;
      n.next = null;
      n.prev = top;
      top = n;
    }
  }
 
  // Pops top element from stack
  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;
    }
  }
 
  // Prints top element of the stack
  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);
  }
 
  // Determines the size of the stack
  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);
  }
 
  // Determines the size of the stack
  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("");
    }
  }
 
  // Driver code
  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();
  }
}
 
// This code is contributed by Saurabh Jaiswal


C#




// A complete working java program to
// demonstrate all stack operations using
// a doubly linked list
using System;
public class GFG {
 
  class Node {
    public int data;
    public Node prev;
    public Node next;
  }
 
  static Node start = null;
  static Node top = null;
 
  // Check if stack is empty
  public static bool isEmpty()
  {
    if (start == null)
      return true;
    return false;
  }
 
  // pushes element onto stack
  public static void push(int d)
  {
    Node n;
    n = new Node();
    n.data = d;
    if (isEmpty()) {
      n.prev = null;
      n.next = null;
 
      // As it is first node if stack
      // is empty
      start = n;
      top = n;
    }
    else {
      top.next = n;
      n.next = null;
      n.prev = top;
      top = n;
    }
  }
 
  // Pops top element from stack
  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;
    }
  }
 
  // Prints top element of the stack
  public static void topelement()
  {
    if (isEmpty()) {
      Console.WriteLine("Stack is empty");
    }
    else {
      Console.WriteLine(
        "The element at top of the stack is : "
        + top.data);
    }
  }
 
  // Determines the size of the stack
  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);
  }
 
  // Determines the size of the stack
  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()
  {
 
    // Code
    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();
  }
}
 
// This code is contributed by lokeshmvs21.


Python3




# A complete working Python program to
# demonstrate all stack operations using
# a doubly linked list
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
 
  # Check if stack is empty
  def isEmpty(self):
    if self.start:
      return False
    return True
 
  # pushes element onto stack
  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
   
  # Determines the size of the stack
  def stacksize(self):
    curr = self.start
    len = 0
    while curr != None:
      len += 1
      curr = curr.next
    print("Size of the stack is : ",len)
 
  # Pops top element from stack
  def pop(self):
    if self.isEmpty():
      print('List is Empty')
      return
    self.top =  self.top.prev
    if self.top != None: self.top.next = None
 
  # Prints the stack
  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()
 
  # Prints top element of the stack
  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




// A complete working javascript program to
// demonstrate all stack operations using
// a doubly linked list
 
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();
 
 
 
// pushes element onto stack if stack is not full
function pushIfNotFull(data) {
    if (!isFull()) {
        push(data);
    }
 
    else {
        console.log("Stack is full, cannot push element");
    }
}
 
// pops top element from stack if stack is not empty
function popIfNotEmpty() {
    if (!isEmpty()) {
        pop();
    }
 
    else {
        console.log("Stack is empty, cannot pop element");
    }
}
 
 
// clears all elements from the stack
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.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads