Understanding Linked List Using Stack in C

Introduction

Managing data efficiently is crucial in programming, and stacks are a widely used data structure for handling operations like undo features, function calls, and expression evaluations. While arrays can be used to implement stacks, they come with fixed sizes and inefficient memory utilization. This is where linked lists offer a dynamic and flexible alternative. In this guide, we will explore how to implement a stack using a linked list in C, covering everything from node structure to stack operations and memory management.

Node Structure

A stack implemented using a linked list consists of nodes where each node contains two elements:

  • Data: The actual value stored.
  • Pointer: A reference to the next node in the stack.

Here’s how we define the node structure in C:

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

This structure ensures efficient memory utilization by dynamically allocating nodes as needed.

Dynamic Memory Allocation

Unlike arrays, linked lists allocate memory dynamically, making them ideal for stacks where the size varies. In C, we use malloc to create new nodes and free to deallocate memory. This approach minimizes wasted space and optimizes resource usage. However, improper memory management can lead to memory leaks, so every allocated node should be properly freed when removed.

Understanding Node Structure

  • Each node consists of data and a pointer to the next node.
  • The top pointer in the stack always refers to the last inserted node.
  • The last node in the stack has a NULL pointer, marking the stack’s end.

Benefits of Linked List Stack in C

  • Dynamic size: Unlike arrays, linked lists do not require predefined sizes.
  • Efficient memory usage: Memory is allocated only when required.
  • No overflow: Unless system memory is exhausted, the stack can grow as needed.

Push Operation Details

To add an element to the stack:

  1. Create a new node using malloc.
  2. Assign data to the node.
  3. Link the new node to the top.
  4. Update the top pointer.

Code example:

void push(struct Node** top, int data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    if (!newNode) {
        printf("Stack overflow\n");
        return;
    }
    newNode->data = data;
    newNode->next = *top;
    *top = newNode;
}

Pop Operation Details

To remove an element:

  1. Check if the stack is empty.
  2. Store the current top node.
  3. Move the top pointer to the next node.
  4. Free the removed node.

Code example:

int pop(struct Node** top) {
    if (*top == NULL) {
        printf("Stack underflow\n");
        return -1;
    }
    struct Node* temp = *top;
    int popped = temp->data;
    *top = temp->next;
    free(temp);
    return popped;
}

Example Code and Visual Representation

Here’s a full implementation of a stack using a linked list:

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

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

void push(struct Node** top, int data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = *top;
    *top = newNode;
}

int pop(struct Node** top) {
    if (*top == NULL) {
        return -1;
    }
    struct Node* temp = *top;
    int popped = temp->data;
    *top = temp->next;
    free(temp);
    return popped;
}

void display(struct Node* top) {
    while (top) {
        printf("%d -> ", top->data);
        top = top->next;
    }
    printf("NULL\n");
}

int main() {
    struct Node* top = NULL;
    push(&top, 10);
    push(&top, 20);
    push(&top, 30);
    display(top);
    printf("Popped: %d\n", pop(&top));
    display(top);
    return 0;
}

Output:

30 -> 20 -> 10 -> NULL
Popped: 30
20 -> 10 -> NULL

Performance and Time Complexity

  • Push operation: O(1) as insertion occurs at the top.
  • Pop operation: O(1) since deletion happens at the top.
  • Memory efficiency: Only necessary memory is allocated dynamically.

Error Handling in Stack Operations

  • Stack underflow: Check if the stack is empty before popping.
  • Stack overflow: Handle memory allocation failures.
  • Memory leaks: Always free removed nodes to prevent leaks.

FAQs

How to implement a stack using singly linked lists? Define a node structure, use dynamic memory allocation, and implement push/pop functions.

How to represent a stack using a linked list in C? Use a struct with a pointer to track the top of the stack.

What is a linked list-based stack? A stack implemented using dynamically allocated nodes.

How to implement stack operations using a linked list? Write functions for push, pop, and display using pointers.

Where is data stored in a linked list in C? Each node contains data, and nodes are linked using pointers.

Conclusion

Stacks are essential in programming, and linked lists provide a dynamic, efficient way to implement them. Understanding their structure, operations, and memory management helps in writing optimized code. If you’re looking to strengthen your data structure skills, check out our Data Science Placement Program and take the first step toward a successful career!