Recommended resources
The freely available resources this lesson will direct you to.
- 3.3 Stack implementation using Linked List | Data Structures and Algorithm Tutorialswww.youtube.com
- Data Structures: Linked List implementation of stackswww.youtube.com
- Stack Using Linked List in C - GeeksforGeekswww.geeksforgeeks.org
- How to Implement a Stack in C With Code Exampleswww.digitalocean.com
In our last lesson, we explored the theoretical trade-offs between arrays and linked lists, concluding that linked lists shine when you need frequent, fast insertions and deletions at the beginning of a sequence. Today, we'll put that theory into practice by tackling a classic use case that perfectly illustrates this strength.
You will learn to implement a stack using a linked list, which will demonstrate the versatility and power of this dynamic data structure. In Module 10, you built a stack with a dynamically-sized array. Now you'll build an alternative version, giving you a deeper appreciation for how the same abstract data type (ADT) can be realized with different underlying structures, each with its own advantages.
1. The Core Concept: Mapping a Stack to a Linked List
Recall that a stack is a Last-In, First-Out (LIFO) structure. The two primary operations are push (add an element) and pop (remove an element), both of which occur at the "top" of the stack.
Our goal is to perform these operations in constant time, . Based on our last lesson, where in a linked list can we both insert and delete a node in time? The answer is at the head of the list.
This gives us a simple and elegant mapping:
- The top of the stack will be the head of the linked list.
push(value)becomesinsertAtHead(value).pop()becomesdeleteFromHead().
This visual representation makes the concept clear:

The head of the linked list serves as the top of our stack. All additions (push) and removals (pop) happen here, ensuring LIFO behavior and O(1) performance.
The following video provides an excellent explanation of why this approach is chosen and the performance implications of using the head versus the tail of the list.
3.3 Stack implementation using Linked List | Data Structures and Algorithm Tutorials
The presenter, Jenny, clearly explains the time complexity trade-offs and justifies why the head of the linked list is the only logical choice for the stack's top.
Watch from the choice of implementation. Focus on her analysis of why performing insertions and deletions at the tail would be an inefficient O(n) operation, reinforcing what we learned in the previous lesson.
2. Implementing the Stack Operations in C
Now that we have the guiding principle—top is head—let's translate this into C code. We'll need a Node structure and a single pointer, which we can call top, to keep track of the head of our list.
#include <stdio.h>
#include <stdlib.h>
// A structure to represent a stack node
struct StackNode {
int data;
struct StackNode* next;
};
// A pointer to the top of the stack
struct StackNode* top = NULL;
With this setup, we can implement the core stack functions. The next video provides a line-by-line walkthrough of the code for push, pop, peek, and display.
3.3 Stack implementation using Linked List | Data Structures and Algorithm Tutorials
This video segment is a practical guide to writing the C functions for a linked list-based stack. It visualizes how the pointers and data change with each operation.
Watch the following sections carefully, as they cover the complete implementation: Push Operation: Watch this segment to understand how to allocate a new node, link it to the existing list, and update the top pointer. Display and Peek: This part covers traversing the list to print its contents (the display function) and how to look at the top element without removing it (peek). Pop Operation: Pay close attention here, especially to the use of a temporary pointer and the free() function to prevent memory leaks.
Let's summarize the logic for each key function based on the video.
The push Function
This function adds a new element to the top of the stack.
- Allocate Memory: Use
mallocto create a newStackNode. - Check for Overflow: If
mallocreturnsNULL, the system is out of memory. This is the linked-list equivalent of a "stack overflow". - Set Data: Assign the passed-in value to the
datafield of the new node. - Link to List: Set the
nextpointer of the new node to point to the currenttop. - Update Top: Update the
toppointer to point to the new node, making it the new head of the list.
The pop Function
This function removes the top element from the stack.
- Check for Underflow: If
topisNULL, the stack is empty. There is nothing to pop. - Store a Temporary Pointer: Create a temporary pointer
tempthat points to the currenttopnode. This is crucial so we don't lose track of the memory we need to deallocate. - Update Top: Move the
toppointer to the next node in the list (top = top->next). - Free Memory: Call
free(temp)to release the memory of the original top node. This step is non-negotiable; forgetting it leads to a memory leak, where your program consumes memory without ever releasing it.
This process is detailed in the DigitalOcean article "How to Implement a Stack in C".
How to Implement a Stack in C With Code Examples
This section highlights a very common and critical error when implementing linked list data structures.
Read the subsection titled "Memory Leaks in Linked Lists". It explains exactly why simply moving the top pointer is not enough and why free() is essential for robust code.
3. A Complete Implementation
You now have all the conceptual pieces to build a fully functional stack using a linked list. The following resource provides a complete, well-structured C program that brings everything together.
Stack Using Linked List in C - GeeksforGeeks
This GeeksforGeeks article provides a clear, step-by-step guide and a full code implementation. It's a great reference to check your own work against.
First, read the "Basic Operations" section. It provides clear algorithms for the push, pop, peek, and isEmpty functions. After reviewing the algorithms, study the full C code example provided in the article. Notice how it structures the program with helper functions like createNode and deleteHead, which makes the main stack functions (push, pop) cleaner and more readable. Try to re-type and run the code yourself to solidify your understanding.
4. Why Was This a Good Idea?
So, why go to the trouble of using a linked list when we already know how to implement a stack with an array? The answer lies in overcoming the array's biggest weakness: its fixed size.
- Dynamic Sizing: A linked list-based stack can grow and shrink as needed at runtime. You never have to decide on a
MAX_SIZEbeforehand. It will only fail if the entire system runs out of memory. - No Wasted Memory: An array-based stack might have a capacity of 1000 but only hold 10 elements, wasting a significant amount of memory. The linked list implementation only allocates memory for the elements that actually exist.
- No "Stack Overflow" Errors: The dreaded stack overflow (from exceeding the array's capacity) is effectively eliminated.
This flexibility is what makes the linked list a "versatile" tool for this job. It adapts perfectly to the problem's needs without the rigid constraints of an array.
Conclusion
In this lesson, you have successfully combined your knowledge of linked lists and stacks to create a more flexible and robust data structure. This is a significant step, as you are now moving beyond implementing basic structures to choosing and building the right structure for a given task.
Key Takeaways:
- A stack can be efficiently implemented using a linked list by mapping the stack's
topto the list'shead. - This approach ensures that
pushandpopoperations are performed in constant time, . - The main advantage of a linked list implementation is its dynamic size, which eliminates the risk of stack overflow and avoids memory waste from pre-allocating a fixed-size array.
- Proper memory management is critical: you must
freethe memory of a popped node to prevent memory leaks.
Preview of the Next Module:
So far, all the data structures we've worked with—arrays, linked lists, stacks, and queues—have been linear. They represent a sequence of items, one after another. In the next module, we will venture into the world of non-linear data structures, starting with trees. You will learn about the terminology of binary trees and discover how their hierarchical structure enables powerful new ways to organize and search for data, far more efficiently than a linear scan would allow.