Write A Program To Implement Stack Using Linked List In C

Published: 12 Nov 2025
Reading Time: 7 min read

Table of Contents

Key Takeaways From the Blog

Introduction

A stack is generally implemented using an array but this kind of limitation of memory occupied by the array being is fixed no matter what the number of elements in the stack is what offers linked lists a dynamic alternative to arrays. Using linked list implementation, the size occupied by the linked list is dynamic. It means that the size will change automatically according to the elements present.

Despite the change in data structure, the core stack operations such as push, pop, and peek maintain their time complexity. In a linked list-based stack, nodes are scattered in memory rather than stored sequentially. Each node contains data and a pointer to the next node in the stack.

Stack overflow happens when there isn't enough memory to create new nodes in the heap. In this setup, the last node's pointer is set to NULL. To align the stack's Last In, First Out (LIFO) behaviour with linked list operations, a top pointer manages tasks like pushing, popping, peeking, and displaying. The top pointer acts as the entry point, making insertion and deletion happen at the beginning of the list.

Node Structure Definition

To implement a stack using a singly linked list in C, you must first define the structure of a node. Each node contains two essential parts:

You can define the node structure using either the struct node declaration or a typedef for convenience.

Example 1: Using struct node

struct node {
    int data;          // Data field to store the value
    struct node *next; // Next pointer to store address of next node
};

Example 2: Using typedef struct node

typedef struct node {
    int data;          // Data field
    struct node *next; // Address of next node
} Node;

Key Points:

By defining this node structure, you lay the groundwork for all stack operations, such as push, pop, and display, as each operation will interact with nodes connected via their next pointers.

Stack Representation and Pointer Management

To efficiently implement a stack using a singly linked list, you must use a dedicated pointer to keep track of the top of the stack at all times. This pointer is often referred to as the head pointer, top pointer, or start pointer.

How It Works

Example Code

struct node* head = NULL; // head pointer (top of the stack), initialized as null pointer

// Pushing a value
struct node* newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = value;
newNode->next = head; // Link new node to the current top
head = newNode;        // Update head to new node

// Popping a value
if (head != NULL) {
    struct node* temp = head;
    head = head->next;  // Move head to the next node
    free(temp);         // Remove the previous topmost node
} else {
    // Stack is empty
}

Important Notes:

Implementation of Stack Using Linked List in C

Unlike arrays, linked lists offer greater flexibility because the stack can expand or contract as needed, avoiding the fixed-size limitations of arrays. Since memory is dynamically allocated for each node, the chances of running into overflow are significantly reduced compared to array-based stacks.

Basic Operations of Linked List Stack in C

In a linked list-based stack, each stack element is represented by a node, which contains two parts: data (the value stored in the node) and next (a pointer to the next node in the stack). The top pointer refers to the topmost node in the stack. Both push() and pop() operations occur at the top of the linked list, and they run in O(1) time.

The following operations can be performed on a stack:

Push Operation

push(): Adds an element to the top of the stack. This operation takes O(1) time because each node is inserted at the top (head) of the linked list.

Algorithm:

Step 1 - Create a new node and allocate memory using malloc().

Step 2 - Check if memory allocation was successful. If not, display "Memory Overflow" and terminate the function.

Step 3 - Assign the input value to the data field of the new node.

Step 4 - Set the next pointer of the new node to point to the current head of the stack.

Step 5 - Update head to point to the new node, making it the top of the stack.

Step 6 - Print a success message indicating the element has been pushed.

Pop Operation

pop(): Removes the top element from the stack. This also takes O(1) time since the top of the stack always points to the most recently added node.

Algorithm:

Step 1 - Check whether the stack is empty (head == NULL).

Step 2 - If it is empty, display "Stack Underflow" and terminate the function.

Step 3 - If the stack is not empty, define a pointer temp and set it to point to head (top of the stack).

Step 4 - Retrieve the value of the top element from temp → data for further use, if needed.

Step 5 - Move the head pointer to the next node (head = head → next).

Step 6 - Free the memory allocated for the temp node.

Step 7 - Print a success message indicating the element has been popped.

Peek Operation

peek(): Returns the top element of the stack without removing it.

Algorithm:

Step 1 - Check whether the stack is empty (head == NULL).

Step 2 - If it is empty, display "Stack is Empty" and terminate the function.

Step 3 - If the stack is not empty, retrieve the value stored in head → data.

Step 4 - Display the retrieved value as the top element of the stack.

Size Operation

size(): Returns the number of elements in the stack.

Algorithm:

Step 1 - Check whether the stack is empty (head == NULL).

Step 2 - If the stack is empty, return size as 0.

Step 3 - If the stack is not empty, initialize a counter variable count to 0.

Step 4 - Define a pointer temp and set it to point to head (top of the stack).

Step 5 - Traverse through the stack using a loop. For each node, increment the count and move temp to the next node (temp = temp → next).

Step 6 - Continue the loop until temp becomes NULL.

Step 7 - Return or display the value of count as the size of the stack.

isEmpty Operation

isEmpty(): Checks if the stack is empty. It returns true if the stack is empty and false otherwise.

Algorithm:

Step 1 - Check the value of the head pointer.

Step 2 - If head == NULL, the stack is empty. Return true or display "Stack is Empty".

Step 3 - If head != NULL, the stack contains elements. Return false or display "Stack is Not Empty".

Code Implementation of Push Operation in C

In a stack implemented using a linked list, adding a node is called the push operation. The process of pushing an element onto the stack in a linked list differs from an array-based implementation.

Algorithm:

Step 1 - Define a node structure with val and next.

Step 2 - Initialize head = NULL.

Step 3 - Allocate memory for a new node (ptr). If allocation fails, display an error and exit.

Step 4 - Input a value and assign it to ptr → val.

Step 5 - If the stack is empty, set ptr → next = NULL and head = ptr.

Step 6 - Otherwise, set ptr → next = head and update head = ptr.

Step 7 - Print a success message.

Main Function: Call push() to add elements to the stack.

Code Example:

#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node
struct node {
    int val;
    struct node* next;
};

// Define the head pointer (top of the stack)
struct node* head = NULL;

// Function to push an element onto the stack
void push() {
    int val;

    // Allocate memory for the new node
    struct node* ptr = (struct node*)malloc(sizeof(struct node));

    // Check if memory allocation failed
    if (ptr == NULL) {
        printf("Unable to push the element. Memory allocation failed.\n");
        return;  // Exit the function if memory allocation fails
    }

    // Prompt user for input
    printf("Enter the value to push: ");
    scanf("%d", &val);

    // Assign the input value to the new node
    ptr->val = val;

    // If the stack is empty, the new node becomes the top node
    if (head == NULL) {
        ptr->next = NULL;  // Set next to NULL as there are no other nodes
        head = ptr;        // Set head to the new node
    } else {
        // Otherwise, insert the new node at the top of the stack
        ptr->next = head;  // Link the new node to the current top
        head = ptr;        // Update head to the new node
    }

    // Print confirmation
    printf("Item %d pushed to stack\n", val);
}

// Main function to test the push operation
int main() {
    push();  // Call push to add an element to the stack
    push();  // Call push again to add another element

    return 0;
}

Output:

Enter the value to push: 10
Item 10 pushed to stack
Enter the value to push: 30
Item 30 pushed to stack

=== Code Execution Successful ===

How it works:

The code defines a stack using a linked list, where each node holds a value and a pointer to the next node. The push() function allocates memory for a new node, asks the user for a value, and assigns it to the node. If the stack is empty, the new node becomes the top. If not, the new node is added to the top, and the head pointer is updated. After the value is pushed onto the stack, the function prints a confirmation message.

Code Implementation of Pop Operation in C

The pop operation removes a node from the top of the stack. This process differs from the array implementation in a linked list implementation of the stack.

Steps Involved:

  1. Check for underflow: Underflow happens when an attempt is made to pop from an empty stack. This occurs if the head pointer is NULL, meaning there are no elements in the stack.
  2. Update the head pointer: Since elements are removed from the top, we delete the node pointed to by the head. The head pointer is then updated to point to the next node in the list, which removes the topmost element from the stack. The removed node's memory is freed to prevent memory leaks.

Algorithm:

Step 1: Create a structure node with val (value) and next (pointer to the next node).

Step 2: Initialize the stack by setting head = NULL.

Step 3: Check if head == NULL to see if the stack is empty.

Step 4: If head is NULL, print "Underflow: Stack is empty" and exit the function.

Step 5: If the stack is not empty, set a pointer ptr to head.

Step 6: Store the value of the top node in a variable item (i.e., item = head->val).

Step 7: Update the head pointer to the next node with head = head->next.

Step 8: Free the memory of the popped node using free(ptr).

Step 9: Print "Item X popped from stack", where X is the value of the popped item.

Main function: Call the pop() function to remove an element from the stack.

Code Example:

#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node
struct node {
    int val;
    struct node* next;
};

// Define the head pointer (top of the stack)
struct node* head = NULL;

// Function to pop an element from the stack
void pop() {
    // Check for underflow (empty stack)
    if (head == NULL) {
        printf("Underflow: Stack is empty\n");
        return;  // Exit if the stack is empty
    }

    // Save the value to be popped
    struct node* ptr = head;   // Temporary pointer to the top node
    int item = head->val;      // Get the value of the top node

    // Update the head pointer to the next node
    head = head->next;

    // Free the memory of the popped node
    free(ptr);

    // Print the popped item
    printf("Item %d popped from stack\n", item);
}

// Main function to test pop
int main() {
    // For testing purposes, add a node and then pop
    // Assuming push() function is available to add elements to the stack
    pop();  // Try to pop from an empty stack (underflow)
    return 0;
}

Output:

Underflow: Stack is empty

=== Code Execution Successful ===

How it works:

The pop() function is meant to remove the top element from the stack. To do this, it first checks if the stack is empty by looking if the head is NULL. If the stack is empty, then it prints an "Underflow" message and stops. If the stack is not empty, it saves the value of the top node. Then, it moves the head to the next node and frees the memory of the old top node. Finally, it prints the value that was removed. This process updates the stack and frees memory properly after each pop.

Key Takeaways So Far

Display the Nodes (Traversing)

Displaying the nodes (traversing) means to iterate through the stack or linked list from the head. Then to print each node's value for the user to see. Traversing continues until the end of the list is reached (NULL).

Algorithm:

Step 1: Create a structure node with val (value) and next (pointer to the next node).

Step 2: Initialize the stack by setting head = NULL.

Step 3: Check if head == NULL to see if the stack is empty.

Step 4: If head is NULL, print "Stack is empty" and exit the function.

Step 5: If the stack is not empty, print "Stack elements:".

Step 6: Set a pointer ptr to head.

Step 7: While ptr is not NULL, print ptr->val.

Step 8: Move ptr to the next node with ptr = ptr->next.

Step 9: Repeat steps 7 and 8 until all elements are printed.

Main function: Call the display() function to display the stack or print "Stack is empty".

Code Example:

#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node
struct node {
    int val;
    struct node* next;
};

// Define the head pointer (top of the stack)
struct node* head = NULL;

// Function to display the elements in the stack
void display() {
    if (head == NULL) {  // Check if the stack is empty
        printf("Stack is empty\n");
        return;
    }

    struct node* ptr = head;  // Temporary pointer to traverse the stack
    printf("Stack elements: \n");
    while (ptr != NULL) {
        printf("%d\n", ptr->val);  // Print the value of the current node
        ptr = ptr->next;           // Move to the next node
    }
}

// Main function to test the display
int main() {
    display(); // Test display with an empty stack
    return 0;
}

Output:

Stack is empty

=== Code Execution Successful ===

How the code works:

The code creates a stack using a linked list. Each node has a value and a pointer to the next node. The stack is managed by the head pointer, which starts as NULL (empty). The display() function checks if the stack is empty. If it's empty, it prints "Stack is empty."

If it is not empty, it prints each node's value. The function goes through the stack by following the next pointers, from the first node to the last. The main() function calls display() to show the stack or say if it's empty.

C Program to Implement All Stack Operations Using Linked List

Here's a complete program that implements all basic stack operations using a linked list in C:

#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node
struct node {
    int val;
    struct node* next;
};

// Define the head pointer (top of the stack)
struct node* head = NULL;

// Function to push an element onto the stack
void push() {
    int val;
    struct node* ptr = (struct node*)malloc(sizeof(struct node));

    if (ptr == NULL) {
        printf("Unable to push the element. Memory allocation failed.\n");
        return;
    }

    printf("Enter the value to push: ");
    scanf("%d", &val);

    ptr->val = val;
    ptr->next = head;  // Point the new node to the current top node
    head = ptr;        // Update the head to the new node

    printf("Item %d pushed to stack\n", val);
}

// Function to pop an element from the stack
void pop() {
    if (head == NULL) {
        printf("Underflow: Stack is empty\n");
        return;
    }

    struct node* ptr = head;
    int item = head->val;

    head = head->next;  // Move the head pointer to the next node
    free(ptr);          // Free the memory of the popped node

    printf("Item %d popped from stack\n", item);
}

// Function to peek at the top element of the stack
void peek() {
    if (head == NULL) {
        printf("Stack is empty. No top element.\n");
    } else {
        printf("Top element is: %d\n", head->val);
    }
}

// Function to display the stack elements
void display() {
    if (head == NULL) {
        printf("Stack is empty\n");
        return;
    }

    struct node* temp = head;
    printf("Stack elements: ");
    while (temp != NULL) {
        printf("%d ", temp->val);
        temp = temp->next;
    }
    printf("\n");
}

// Function to check if the stack is empty
int isEmpty() {
    return (head == NULL);
}

// Function to return the size of the stack
int size() {
    int count = 0;
    struct node* temp = head;

    while (temp != NULL) {
        count++;
        temp = temp->next;
    }
    return count;
}

// Main function to test the stack operations
int main() {
    int choice;

    while (1) {
        printf("\nStack Operations Menu:\n");
        printf("1. Push\n");
        printf("2. Pop\n");
        printf("3. Peek\n");
        printf("4. Display\n");
        printf("5. Check if Stack is Empty\n");
        printf("6. Get Stack Size\n");
        printf("7. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                push();
                break;
            case 2:
                pop();
                break;
            case 3:
                peek();
                break;
            case 4:
                display();
                break;
            case 5:
                if (isEmpty()) {
                    printf("Stack is empty\n");
                } else {
                    printf("Stack is not empty\n");
                }
                break;
            case 6:
                printf("Stack size: %d\n", size());
                break;
            case 7:
                printf("Exiting...\n");
                exit(0);
            default:
                printf("Invalid choice, please try again\n");
        }
    }

    return 0;
}

Sample Output:

Stack Operations Menu:
1. Push
2. Pop
3. Peek
4. Display
5. Check if Stack is Empty
6. Get Stack Size
7. Exit
Enter your choice: 1
Enter the value to push: 10
Item 10 pushed to stack

Stack Operations Menu:
1. Push
2. Pop
3. Peek
4. Display
5. Check if Stack is Empty
6. Get Stack Size
7. Exit
Enter your choice: 3
Top element is: 10

Stack Operations Menu:
1. Push
2. Pop
3. Peek
4. Display
5. Check if Stack is Empty
6. Get Stack Size
7. Exit
Enter your choice: 2
Item 10 popped from stack

How it works:

In this program we implement stack operations using a linked list. The push() function adds an element to the top of the stack by creating a new node, assigning it the given value, and updating the head pointer. The pop() function removes the top element, checks for underflow (empty stack), and updates the head pointer. The peek() function displays the top element without removing it, while the display() function shows all elements in the stack. The isEmpty() function checks if the stack is empty, and size() counts the total elements. The program provides an interactive menu for these operations.

Complete Program Example: Stack Using Singly Linked List in C

Below is a full example of a stack implementation in C using a singly linked list. This program demonstrates all the essential stack operations—push, pop, peek, display, isEmpty, and size—using dynamic memory allocation. For demonstration purposes, the stack is limited to a maximum size of 5 elements using #define size 5.

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define size 5

// Define the node structure for the singly linked list
struct node {
    int data;
    struct node *next;
};

// Head pointer representing the top of the stack
struct node* head = NULL;
int current_size = 0;

// Function to push an element onto the stack
void push() {
    if (current_size == size) {
        printf("Stack Overflow: Maximum size reached (%d)\n", size);
        return;
    }

    int val;
    printf("Enter the value to push: ");
    scanf("%d", &val);

    struct node* newNode = (struct node*)malloc(sizeof(struct node));
    if (newNode == NULL) {
        printf("Memory allocation failed.\n");
        return;
    }

    newNode->data = val;
    newNode->next = head;
    head = newNode;
    current_size++;

    printf("Item %d pushed to stack\n", val);
}

// Function to pop an element from the stack
void pop() {
    if (head == NULL) {
        printf("Underflow: Stack is empty\n");
        return;
    }

    struct node* temp = head;
    int popped = head->data;
    head = head->next;
    free(temp);
    current_size--;

    printf("Item %d popped from stack\n", popped);
}

// Function to peek at the top element
void peek() {
    if (head == NULL) {
        printf("Stack is empty. No top element.\n");
    } else {
        printf("Top element is: %d\n", head->data);
    }
}

// Function to display all elements in the stack
void display() {
    if (head == NULL) {
        printf("Stack is empty\n");
        return;
    }

    struct node* temp = head;
    printf("Stack elements: ");
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

// Function to check if the stack is empty
int isEmpty() {
    return (head == NULL);
}

// Function to return the size of the stack
int stack_size() {
    return current_size;
}

// Main function to test stack operations
int main() {
    int choice;

    while (1) {
        printf("\nStack Operations Menu:\n");
        printf("1. Push\n");
        printf("2. Pop\n");
        printf("3. Peek\n");
        printf("4. Display\n");
        printf("5. Check if Stack is Empty\n");
        printf("6. Get Stack Size\n");
        printf("7. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                push();
                break;
            case 2:
                pop();
                break;
            case 3:
                peek();
                break;
            case 4:
                display();
                break;
            case 5:
                if (isEmpty())
                    printf("Stack is empty\n");
                else
                    printf("Stack is not empty\n");
                break;
            case 6:
                printf("Stack size: %d\n", stack_size());
                break;
            case 7:
                printf("Exiting...\n");
                exit(0);
            default:
                printf("Invalid choice, please try again\n");
        }
    }

    return 0;
}

How It Works:

Key Takeaways So Far

Output and Sample Execution

Below are typical outputs you might encounter when running the stack program. These samples show how stack operations affect the linked list and how the program responds to different scenarios.

Sample Run

Stack Operations Menu:
1. Push
2. Pop
3. Peek
4. Display
5. Check if Stack is Empty
6. Get Stack Size
7. Exit
Enter your choice: 1
Enter the value to push: 25
Item 25 pushed to stack

Enter your choice: 1
Enter the value to push: 40
Item 40 pushed to stack

Enter your choice: 4
Stack elements: 40 25

Enter your choice: 2
Number popped = 40
// free(temp) releases memory for the popped node
// top-- decreases the stack size

Enter your choice: 4
Stack elements: 25

Enter your choice: 2
Number popped = 25
// free(temp) releases memory
// top-- decreases stack size

Enter your choice: 2
Stack is empty

Enter your choice: 6
Stack size: 0

Enter your choice: 5
Stack is empty

Explanation

Notes

Real-Life Applications of Stack

Here are some real-world applications of stack data structures:

Bottom Line: Stacks are essential in recursion, expression evaluation, undo features, and efficient function call management.

Conclusion

Learning stacks is crucial for coding students as it enhances problem-solving skills and understanding of key data structures. Stacks are fundamental in managing function calls and memory and handling various real-life applications like expression evaluation and history tracking. Mastering stack operations strengthens algorithmic thinking, enabling students to write efficient and optimised code. It forms the foundation for understanding more advanced concepts and algorithms, making it an essential tool for aspiring programmers.

Why does it matter?

Understanding stacks implemented with linked lists is crucial because it combines dynamic memory management with core data structure concepts. This knowledge helps learners write efficient, flexible programs and prepares them for advanced topics like recursion, expression evaluation, and algorithm optimization.

Practical advice for learners

Frequently Asked Questions

What is a stack using a linked list in C?

In C, a stack employs a linked list, a data structure in which elements are inserted or deleted from the topmost node, known as the peak node. It conforms to the Last In First Out (LIFO) policy using nodes connected by a link.

How is the stack represented in the linked list?

The stack is represented by a linked list where each node contains a value and a pointer to the next node. The head pointer represents the top of the stack.

Is the linked list the same as the stack?

A linked list is a generic data structure that stores the element. A stack is one of the data structures that follow the LIFO principle and is generally implemented using a linked list.

What are the advantages of using a linked list to implement a stack?

Using a linked list for a stack allows dynamic memory allocation. It means the stack can grow or shrink as needed, avoiding size limitations and overflow issues typical with arrays.

How does stack overflow occur in a linked list implementation?

Stack overflow in a linked list implementation occurs when the system runs out of memory to allocate for new nodes. It's usually due to the excessive pushing of elements without proper memory management.


Related Articles


Source: NxtWave CCBP
Original URL: https://www.ccbp.in/blog/articles/write-a-program-to-implement-stack-using-linked-list-in-c