Linked List Data Structure
- Published on 🕒 4 min read
- Authors

- Name
- Mohammad Mustakim Hassan
- @mmhshayer
Introduction
A linked list is a linear data structure consisting of a sequence of elements, called nodes, where each node contains a data value and a reference (pointer) to the next node in the sequence. Unlike arrays, linked lists do not store elements in contiguous memory locations.
Operations
Linked lists support various operations, including:
- Insertion: Inserting elements at the beginning, end, or any position in the linked list.
- Deletion: Removing elements from the linked list.
- Traversal: Iterating over all elements of the linked list to perform certain operations.
- Search: Searching for elements in the linked list.
Example
Consider a singly linked list representing a sequence of integers:
const scores = [85, 92, 78, 95, 88];
const thirdScore = scores[2]; // Output: 78
Insertion: If we want to insert the element 15 at the beginning, we create a new node with value 15 and point it to the current head:
scores.push(90);
console.log(scores); // Output: [85, 92, 78, 95, 88, 90]
Deletion: If we want to delete the node with value 7, we update the next reference of the previous node to skip the node with value 7:
scores.splice(1, 1);
console.log(scores); // Output: [85, 78, 95, 88, 90]
Traversal: We can traverse the linked list to print all elements:
let sum = 0;
for (let i = 0; i < scores.length; i++) {
sum += scores[i];
}
const average = sum / scores.length;
console.log(average); // Output: 87.6
Search: To find if the value 5 exists in the linked list, we traverse the list until we find the node with value 5.
const index = scores.indexOf(88);
console.log(index); // Output: 3 (index of score 88)
Advantage
- Dynamic Size: Linked lists can dynamically grow and shrink in size, making them suitable for situations where the size of the data structure may change frequently.
- Efficient Insertions and Deletions: Insertions and deletions in linked lists can be performed in constant time, regardless of the size of the list.
- Memory Efficiency: Linked lists utilize memory more efficiently than arrays, as they only allocate memory for elements when needed.
Disadvantage
- Sequential Access: Linked lists do not support random access to elements like arrays, requiring sequential traversal to access elements at specific positions.
- Memory Overhead: Linked lists require additional memory space for storing references to the next nodes, leading to higher memory overhead compared to arrays.
- Complexity in Traversal: Traversing a linked list may require more complex code compared to arrays, especially in languages without built-in iterator support.
Application
Linked lists find applications in various scenarios, including:
- Dynamic Memory Allocation: Managing memory dynamically in languages like C and C++ using memory pools and free lists.
- Implementation of Stacks and Queues: Implementing stack and queue data structures using linked lists for efficient insertions and deletions.
- Sparse Data Structures: Representing sparse data structures efficiently, where most elements are empty or zero.
- Polynomial Manipulation: Storing and manipulating polynomial expressions in symbolic mathematics libraries.
Example JavaScript Implementation
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
}
insertAtBeginning(data) {
const newNode = new Node(data);
newNode.next = this.head;
this.head = newNode;
}
insertAtEnd(data) {
const newNode = new Node(data);
if (!this.head) {
this.head = newNode;
return;
}
let current = this.head;
while (current.next) {
current = current.next;
}
current.next = newNode;
}
deleteNode(data) {
if (!this.head) return;
if (this.head.data === data) {
this.head = this.head.next;
return;
}
let current = this.head;
while (current.next) {
if (current.next.data === data) {
current.next = current.next.next;
return;
}
current = current.next;
}
}
printList() {
let current = this.head;
while (current) {
console.log(current.data);
current = current.next;
}
}
search(data) {
let current = this.head;
while (current) {
if (current.data === data) {
return true;
}
current = current.next;
}
return false;
}
}
// Example usage
const linkedList = new LinkedList();
linkedList.insertAtEnd(3);
linkedList.insertAtEnd(7);
linkedList.insertAtEnd(11);
linkedList.insertAtEnd(5);
linkedList.insertAtEnd(9);
linkedList.insertAtBeginning(15);
linkedList.deleteNode(7);
linkedList.printList(); // Output: 15, 3, 11, 5, 9
console.log(linkedList.search(5)); // Output: true