If you are learning data structures, a Linked List is one of the data structures you should know, albeit not so common, linked lists are similar to...

If you are learning data structures, a Linked List is one of the data structures you should know, albeit not so common, linked lists are similar to Lists (or arrays); you probably never heard or used them until now, but in the right context they prove to be useful.
In this article, you will learn:
A linked list is a sequence of data elements, which are connected together via links. Each element (node) in a linked list contains a connection to another data element in form of a pointer.
That every element in a linked list is called a Node, and every node contains a data (value to be stored) and next (reference to the next node) fields.

A linked list therefore is a collection of nodes, with the last node pointing to None

In a linked list, the time complexity for the operations is given as:
Space complexity however is O(n).
There are 3 main types of linked lists;


This comes in 2 parts, creating our list Node, and the Linked List itself. So, first thing first, create a class to represent each Node of the linked list
class Node:def __init__(self, data):self.data = dataself.next = None
As you can see each node contains just 2 fields, the data, and next.
Next, create a class to represent your linked list :
class LinkedList:def __init__(self, nodes=None):self.head = Noneif nodes is not None:node = Node(data=nodes.pop(0))self.head = nodefor n in nodes:node.next = Node(data=n)node = node.next
Let's update each of our classes with a repr function so our new code looks like this :
class Node:def __init__(self, data):self.data = dataself.next = Nonedef __repr__(self):return self.dataclass LinkedList:def __init__(self, nodes=None):self.head = Noneif nodes is not None:node = Node(data=nodes.pop(0))self.head = nodefor n in nodes:node.next = Node(data=n)node = node.nextdef __repr__(self):node = self.headnodes = []while node is not None:nodes.append(node.data)node = node.nextnodes.append("None")return " -> ".join(nodes)
The code above would rightly allow us to create a linked list, notice that in the LinkedList init function if the node is not passed we initialized it to None.
my_list = LinkedList()firstNode = Node("1")my_list.head = firstNodesecondNode = Node("2")firstNode.next = secondNodeprint(my_list)>>> 1 -> 2 -> None
To help us use our linked lists even more efficiently, we would implement some methods to:
Traversing a linked list means iterating through the list, and we add the iter function to allow us to replicate the same behavior from regular lists (arrays)
def __iter__(self):node = self.headwhile node is not None:yield nodenode = node.next
The code above goes through the list if it does not equal to None and yields every node before re-assigning the node to the next node if it exists.
def add_at_beginning(self, node):node.next = self.headself.head = node
In the above code, you're setting the next value to the present head value before re-assigning head to the new node
def add_at_end(self, node):if self.head is None:self.head = nodereturnfor current in self:passcurrent.next = node
While inserting at the end is similar to inserting at the beginning, first, you want to traverse the whole list until you reach the end. Next, you want to set current as the last node on the list. Finally, you want to add the new node as the next value of that current.
class Node:def __init__(self, data):self.data = dataself.next = Nonedef __repr__(self):return self.dataclass LinkedList:def __init__(self, nodes=None):self.head = Noneif nodes is not None:node = Node(data=nodes.pop(0))self.head = nodefor elem in nodes:node.next = Node(data=elem)node = node.nextdef __repr__(self):node = self.headnodes = []while node is not None:nodes.append(node.data)node = node.nextnodes.append("None")return " -> ".join(nodes)# Traverse a Linked Listdef __iter__(self):node = self.headwhile node is not None:yield nodenode = node.next# Insert a new node at the beginningdef add_at_beginning(self, node):node.next = self.headself.head = node# Insert a new node at the enddef add_at_end(self, node):if self.head is None:self.head = nodereturnfor current_node in self:passcurrent_node.next = node
To wrap up a final example, have a look at how it works:
my_list = LinkedList()firstNode = Node("1")secondNode = Node("2")my_list .head = firstNodefirstNode.next = secondNodemy_list.add_at_beginning(Node("3"))my_list.add_at_end(Node("4"))print(my_list)>>> 3 -> 1 -> 2 -> 4 -> None
In this article, you learned quite a few things, The most important are:
I hope you enjoyed reading it as much as I enjoyed writing it :)
I'm Jide, a Full-Stack Software Engineer with penchant for Web/App development. I like scratching my own itch and writing about Web Technologies, UI/UX case studies, and Tech-bits thereof. During my spare time, I'm an autodidact polymath acquiring knowledge from various resources online.
© 2026 Jide Abdul-Qudus. All rights reserved.