Table of contents
1.
Introduction
2.
Problem Statement
2.1.
Basic operations of stack
3.
Algorithm of Stack Implementation Using Singly Linked List
3.1.
push() Operation:
3.2.
pop() Operation:
3.3.
top_element() Operation:
3.4.
isEmpty() Operation:
3.5.
print_stack() Operation:
3.6.
Code in C++
3.7.
C++
3.8.
Code in Java
3.9.
Java
3.10.
Code in Python
3.11.
Python
3.12.
Complexity Analysis
4.
Benefits of implementing a stack using a singly linked list:
5.
Frequently Asked Questions
5.1.
What is a stack?
5.2.
What does the stack work?
6.
Conclusion
Last Updated: Mar 27, 2024
Easy

Implement Stack using a Singly Linked List

Author Sandeep Kamila
3 upvotes
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

A Stack is one of the most fundamental and extremely used Data structures. Linked Lists also fall in the same category as stacks having a wide range of usages. There are various ways of implementing a stack, it may be using a Queue, an Array, or any other Data Structure. In this article, we are going to take a look at how to implement a Stack using a Linked List.

Stacks

Problem Statement

Implement stack using a singly linked list that supports the basic operations of stack data structure such as push(), pop(), top(), isEmpty(), and follows the last in first out order(LIFO).

Basic operations of stack

  • push(): it pushes an element into the stack data structure.
  • pop(): it removes the top element of the stack.
  • top_element(): it gives the value of the top element of the stack.
  • isEmpty(): it returns true if the stack is empty else returns false.
  • print_stack(): it prints the contents of the stack in LIFO order.

Algorithm of Stack Implementation Using Singly Linked List

To implement a stack using a singly linked list, we make some changes in the singly linked list to make it work as a stack. Here the top of the stack is the head of the linked list. Initially, the head pointer of the linked list is pointing to NULL.

push() Operation:

We attach the new node in front of the linked list to follow LIFO(last in first out) order like the stack data structure.

Steps:

  • Create a new node temp.
  • Point temp’s next as the head, temp->next = head.
  • Finally, make the temp node as the new head, head = temp.
     

Example:

  • push(5)

Initially, the head of the linked list = NULL.

  • Create a temp node of the given value

 

Node
  • temp->next = head

 

Node
  • head = temp

 

Node
  • push(3)

    Repeat the above steps.

 

List

 

pop() Operation:

We remove the elements from the front of the linked list to follow the LIFO( last in first out) order as the stack data structure.

Steps:

  • If the head is NULL, print “stack is empty”.
  • Else create a temp node and store the head in the temp node.
  • Make head as the head’s next node, head = head->next.
  • Delete the temp node.

 

Example: 

Initially, the linked list is:

List
  • pop()

Steps:

  • Create a temp node and store the head of the list in it.


     
List
  • head = head->next.


     
List
  • Delete temp.

     
List



 

top_element() Operation:

If the linked list is empty, print “stack is empty”. Else return the data of the head node.

isEmpty() Operation:

If the head is pointing to the NULL, return true else, return false.

print_stack() Operation:

Steps:

  • Declare a curr pointer pointing to the head of the list.
  • Run a while loop till curr!=NULL.
  • Print the curr->data and do curr=curr->next.

 

You can also watch our video on this topic for a visual understanding of the agenda at hand. 

Code in C++

  • C++

C++

#include <bits/stdc++.h>
using namespace std;

struct node
{
int data;
node* next;
};

struct node* head = NULL;

void push(int x)
{
node* temp;
temp = new node();
temp->data = x;
temp->next = head;
head = temp;
}

bool isEmpty()
{
if (head == NULL)
return true;
else
return false;
}

int top_element()
{

if (head == NULL)
{
cout << "stack is empty" << endl;
}
else
return head->data;

}

void pop()
{
node* temp;

if (isEmpty())
{
cout << "stack is empty" << endl;
}
else
{
temp = head;
head = head->next;
delete(temp);
}
}

void print_stack()
{
struct node* curr;

if (isEmpty())
{
cout << "stack is empty" << endl;
}
else
{
curr = head;
cout << "Elements are: ";
while (curr != NULL)
{

cout << curr->data << " ";

curr = curr->next;
}
cout << endl;
}
}

int main()
{

push(5);
push(3);
push(6);
print_stack();

isEmpty();
cout << "Top: "
<< top_element() << endl;

pop();
print_stack();

cout << "Top: "
<< top_element() << endl;

return 0;
}
You can also try this code with Online C++ Compiler
Run Code

Output

Output

Must Read Stack Operations

Code in Java

  • Java

Java

// Main class
public class Main {
static class StackNode {
int data;
StackNode next;
StackNode(int data) {
this.data = data;
}
}

StackNode root;

// Push method push element to the head of linked list
public void push(int data)
{
StackNode newNode = new StackNode(data);
if (root == null) {
root = newNode;
}
else {
StackNode temp = root;
root = newNode;
newNode.next = temp;
}
}

// pop method pop element from head and return it's data
public int pop()
{
int popped;
if (root == null) {
System.out.println("Stack is Empty");
return 0;
}
else {
popped = root.data;
root = root.next;
return popped;
}
}

// top_element will return the top of the stack
public int top_element()
{
if (root == null) {
System.out.println("Stack is empty");
return Integer.MIN_VALUE;
}
else {
return root.data;
}
}

public static void main(String[] args)
{
Main obj = new Main();
obj.push(5);
obj.push(2);
obj.push(8);
obj.push(7);

System.out.println(obj.top_element());
System.out.println(obj.pop());

System.out.println(obj.top_element());
System.out.println(obj.pop());

System.out.println(obj.top_element());
System.out.println(obj.pop());


}
}
You can also try this code with Online Java Compiler
Run Code

Output

Output

Code in Python

  • Python

Python

# Node class
class Node:
def __init__(self,data):
self.data = data
self.next = None

# Stack class
class Stack:

# constructor initializing head with None
def __init__(self):
self.head = None

# Checks if stack is empty
def isempty(self):
return True if self.head == None else False


# push method adds element to the start of stack
def push(self,data):
if self.head == None:
self.head=Node(data)
else:
new_node = Node(data)
new_node.next = self.head
self.head = new_node


# returns the data of the head node
def topElement(self):
if self.isempty():
return None
else:
return self.head.data


# pop method will remove the current head and return its value
def pop(self):
if self.isempty():
return None
else:
popped_node = self.head
self.head = self.head.next
popped_node.next = None
return popped_node.data



# Driver code
stack_obj = Stack()

stack_obj.push(5)
stack_obj.push(2)
stack_obj.push(7)
stack_obj.push(8)

print(stack_obj.topElement())
print(stack_obj.pop())

print(stack_obj.topElement())
print(stack_obj.pop())

print(stack_obj.topElement())
print(stack_obj.pop())
You can also try this code with Online Python Compiler
Run Code

Output

Output

Complexity Analysis

Time complexity:

  • push(): O(1), as we are not traversing the whole 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 head node.
  • print_stack(): As we are traversing through the whole list it will be O(n), where n is the number of nodes present in the linked list.
     

Space complexity: O(1), as we require constant extra space.

Benefits of implementing a stack using a singly linked list:

There are several advantages to implementing a stack using a singly linked list compared to an array-based approach:

  1. Dynamic Size: Unlike arrays, which have a fixed size defined at allocation, a singly linked list can grow or shrink as needed. This makes it ideal for situations where the size of the stack is unknown beforehand or can vary significantly during program execution. No risk of stack overflow due to exceeding the predefined size.
  2. Efficient Memory Management: Linked lists only allocate memory for the nodes they contain, leading to more efficient memory utilization. Arrays might reserve extra space even if not fully used. This is particularly beneficial for large stacks or when memory resources are limited.
  3. Ease of Insertion and Deletion: Since insertion and deletion in a linked list happen at the beginning (top of the stack), these operations are very efficient. Only the head pointer needs to be updated, requiring minimal modifications to the existing list structure.
  4. No Fragmentation: Unlike arrays, where deleted elements leave gaps leading to fragmentation, linked lists do not suffer from this issue. Memory allocation and deallocation are simpler as nodes can be easily removed without affecting the overall structure.
  5. Simpler Implementation: The logic for implementing basic stack operations (push and pop) using a singly linked list is often considered simpler and more intuitive compared to an array-based approach.

Must Read Python List Operations

Frequently Asked Questions

What is a stack?

A stack is a linear data structure in which operations are performed in a specific order. The order can be LIFO (last-in, first-out) or FILO (first in, first out) (First In Last Out).

What does the stack work?

A stack is a type of linear data structure in which elements are stacked on top of one another. Only the most recent element added, i.e. the element at the top of the stack, can be accessed. A stack, in other words, is a Last In First Out (LIFO) structure. It is the inverse of a queue, which operates on a first-come, first-served basis (FIFO).

Conclusion

So, this article discussed the approach to implementing a stack using a singly linked list and all the steps to implement the basic operations of the stack like push(), pop(), top(), and isEmpty() with examples and code in C++.

Recommended Reading:

 

To learn more about Data Structures and Algorithms, you can enroll in our DSA in C++ Course.

Thank you for reading!

Live masterclass