Back to Data Structures & Algorithms
2026-01-087 min read

Linked List Operations: Traverse, Insert and Delete (Data Structures & Algorithms)

Learn Linked List Operations: Traverse, Insert and Delete (Data Structures & Algorithms) step by step with clear examples and exercises.

Why This Matters

Welcome to this full guide on Linked Lists! In this tutorial, we'll delve into the essential operations of a linked list: traversal, insertion, and deletion using Python. By understanding these concepts, you'll be well-equipped for various coding challenges, interviews, and real-world programming scenarios.

Prerequisites

To fully grasp this lesson, you should have a good understanding of the following topics:

  1. Basic Python Syntax
  2. Data Structures (Arrays, Lists)
  3. Control Structures (for loops, if statements)
  4. Classes and Objects in Python

Core Concept

A linked list is a linear data structure consisting of nodes where each node contains a data field and a reference (link or pointer) to the next node in the sequence. In Python, we can create our own linked list implementation using classes and objects.

Creating a Linked List Node

First, let's define a Node class that will represent each node in our linked list:

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

In this code, we create the Node class with an initializer (__init__) that accepts a single argument data. The node instance will have two attributes: data, which stores the value of the current node, and next, which is used to link the current node to the next one in the sequence.

Creating a Linked List

Now that we have our Node class, let's create a linked list by connecting multiple nodes together:

class LinkedList:
def __init__(self):
self.head = None

def add_to_end(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
return
current = self.head
while current.next:
current = current.next
current.next = new_node

In this code, we create a LinkedList class with an initializer (__init__) that initializes the head of the linked list to None. The add_to_end() method accepts a data argument and creates a new node with that data. If the linked list is empty, it sets the head to the new node. Otherwise, it iterates through the existing nodes until it reaches the end of the list, then links the new node to the last node in the sequence.

Traversal

Traversing a linked list means visiting each node and accessing its data. We can implement this functionality using a helper method called traverse():

def traverse(linked_list):
current = linked_list.head
while current:
print(current.data)
current = current.next

In this code, we define the traverse() function that accepts a linked_list argument and initializes a variable current to the head of the linked list. We then enter a loop that continues until current is None. Inside the loop, we print the data of the current node and move current to the next node by assigning it the value of current.next.

Insertion

Inserting a new node at a specific position in the linked list can be achieved using the following method:

def insert_at(self, data, index):
if index < 0:
raise ValueError("Index must be non-negative")

if index == 0:
self.head = Node(data)
return

current = self.head
for _ in range(index - 1):
if not current:
raise IndexError("List index out of range")
current = current.next

new_node = Node(data)
new_node.next = current.next
current.next = new_node

In this code, we define the insert_at() method for our LinkedList class. It accepts a data argument (the value to be inserted) and an index argument (the position where the node should be inserted). The method first checks if the index is non-negative and raises an error if it's not. If the index is 0, it creates a new node with the given data and sets it as the head of the linked list. Otherwise, it iterates through the existing nodes until it reaches the desired position (index - 1). Once it finds the correct position, it creates a new node with the given data and links it to the next node in the sequence.

Deletion

Deleting a node from the linked list can be accomplished using the following method:

def delete_node(self, data):
if not self.head:
raise ValueError("List is empty")

if self.head.data == data:
self.head = self.head.next
return

current = self.head
while current.next and current.next.data != data:
current = current.next

if not current.next:
raise ValueError(f"{data} not found in the list")

current.next = current.next.next

In this code, we define the delete_node() method for our LinkedList class. It accepts a data argument (the value of the node to be deleted). The method first checks if the linked list is empty and raises an error if it is. If the head of the linked list has the desired data, it sets the head to the next node in the sequence. Otherwise, it iterates through the existing nodes until it finds the node with the desired data or reaches the end of the list. Once it finds the correct node, it links the previous node (current) to the next node after the one to be deleted.

Worked Example

Let's create a linked list and perform various operations on it:

linked_list = LinkedList()
linked_list.add_to_end(1)
linked_list.add_to_end(2)
linked_list.add_to_end(3)
linked_list.add_to_end(4)
linked_list.traverse() # Output: 1 2 3 4
linked_list.insert_at(0, 0)
linked_list.traverse() # Output: 0 1 2 3 4
linked_list.delete_node(4)
linked_list.traverse() # Output: 0 1 2

In this example, we create a new linked list and add four nodes (1, 2, 3, 4) to the end of it. We then traverse the list to verify its contents. Next, we insert a new node with value 0 at the beginning of the list and traverse the list again to check its updated contents. Finally, we delete the last node (4) from the list and traverse it once more to confirm that the deletion was successful.

Common Mistakes

  1. Forgetting to handle edge cases: Always remember to handle situations where the linked list is empty or when the desired index is out of range.
  2. Not properly linking nodes: Ensure that you correctly link each new node to its preceding node in the sequence.
  3. Accessing nonexistent nodes: Be careful not to access nodes that do not exist in the linked list, such as trying to delete a node with a value that does not appear in the list.
  4. Incorrect implementation of insertion and deletion methods: Make sure your insert_at() and delete_node() methods are correctly implemented according to the problem requirements.

Practice Questions

  1. Implement a method to append multiple values to the end of a linked list in one go (e.g., add_many(self, data)).
  2. Implement a method to find the length of a linked list (i.e., the number of nodes it contains).
  3. Implement a method to reverse a linked list.
  4. Implement a method to check if a given value exists in the linked list without traversing the entire list (use an O(1) operation).
  5. Implement a method to merge two sorted linked lists into a single sorted linked list.

FAQ

  1. Why use a linked list instead of an array? Linked lists allow for dynamic resizing, as nodes can be easily added or removed without rearranging the entire data structure like in arrays. However, accessing elements in a linked list is slower than in arrays due to the need to traverse through the links between nodes.
  2. Can I use Python's built-in list for this? While it is possible to implement some linked list operations using Python's built-in list (e.g., appending elements), a custom implementation provides better understanding of the underlying data structure and allows for more efficient solutions in certain scenarios, such as when dealing with large or dynamically changing data sets.
  3. Why do we use None instead of 0 to represent an empty linked list? Using None is a common convention in Python for representing null or empty values, whereas using 0 could be misleading since it can also represent a valid data value in a linked list node.
  4. What are the advantages and disadvantages of a linked list compared to other data structures like arrays and stacks? Advantages include dynamic resizing, efficient insertion and deletion (in the middle of the list), and the ability to store large amounts of data without preallocating memory. Disadvantages include slower access times due to the need to traverse through links between nodes, and increased memory usage compared to arrays due to the additional space required for pointers or links.
  5. Can I create a circular linked list? Yes, it is possible to create a circular linked list by linking the last node back to the first node. This can be useful in certain algorithms, such as those involving cycles or graph traversals. However, it may complicate some operations and should be used with caution.
Linked List Operations: Traverse, Insert and Delete (Data Structures & Algorithms) | Data Structures & Algorithms | XQA Learn