Skip to Content
DocsData Structures and AlgorithmsLinked ListsSingly Linked Lists

Singly Linked Lists

What is Linked lists?

A linked list is a linear data structure where elements are stored in nodes. Each node contains

  • value - The actual data (exp: character, integer, object, etc)
  • next - The reference (or pointer) to the next node in the sequence
OperationBig-O TimeNotes
Access (by index)O(n)Must traverse from head (avg ~ n/2 → O(n))
Search (by value)O(n)Linear scan
Insert (at head)O(1)Update head pointer
Insert (at tail)O(n)O(1) if you maintain a tail pointer
Insert (given previous node)O(1)Insert after a known node; otherwise O(n)
Delete (given previous node / head)O(1)O(1) when you have the previous node; deleting by node-only ref can be O(1) using the copy-trick but can’t remove tail
Delete (by index/value)O(n)Must locate node (and previous) first
Display / TraverseO(n)Visit every node

How it works?

Nodes are linked together in a chain through the “next” pointers. You will start at the head and follow the pointers from one node to the next until you reach the null (end of the list).

Imagine we have a list of numbers like;

  • The head points to the node 1
  • The tail points to null
  • The node for 1 has a “next” pointer that points to the node with 2. This continues until the node with 4, whose “next” pointer is null

Circular Linked List

A circular linked list is actually same as a singly linked list, but the tail node points back to the head node instead of null. This creates a circular structure where you can traverse the list indefinitely.

Singly Linked List Implementation

singly_linked_list.py
class Node: def __init__(self, value) -> None: self.value = value self.next = None class LinkedList: def __init__(self) -> None: self.head = None self.size = 0 def append(self, data) -> None: new_node = Node(data) if not self.head: self.head = new_node else: current = self.head while current.next: current = current.next current.next = new_node self.size += 1 def insert(self, index: int, data) -> None: if index < 0 or index > self.size: raise IndexError("Index out of bounds") new_node = Node(data) current = self.head if index == 0: self.prepend(data) return else: # You need to find the previous node before the index # and adjust the pointers accordingly prev = None for _ in range(index): prev = current current = current.next prev.next = new_node new_node.next = current self.size += 1 def get(self, index: int): if index < 0 or index >= self.size: raise IndexError("Index out of bounds") current = self.head i = 0 while current: if i == index: return current.value i += 1 current = current.next def remove(self, index: int): if index < 0 or index >= self.size: raise IndexError("Index out of bounds") if not self.head: raise IndexError("Pop from empty list") current = self.head if index == 0: self.head = current.next else: i = 0 prev = None while current: if i == index: prev.next = current.next break else: i += 1 prev = current current = current.next self.size -= 1 def prepend(self, data) -> None: new_node = Node(data) if self.head: new_node.next = self.head self.head = new_node self.size += 1 def push(self, data) -> None: self.prepend(data) def pop(self): if not self.head: raise IndexError("Pop from empty list") prev = None current = self.head while current.next: prev = current current = current.next # current is tail if prev: prev.next = None else: # only one element self.head = None self.size -= 1 def is_empty(self) -> bool: return self.size == 0 def __len__(self) -> int: return self.size def display(self) -> None: current = self.head res = [] while current: res.append(str(current.value)) current = current.next print(" -> ".join(res)) linked_list = LinkedList() linked_list.append(10) linked_list.append(20) linked_list.append(30) linked_list.display() linked_list.insert(1, 15) linked_list.display() linked_list.prepend(5) linked_list.display() linked_list.pop() linked_list.display() linked_list.remove(1) linked_list.display()

Singly Linked List Visualization

Singly Linked List Visualization
Head → 0x3000
Tail → 0x3200
0x3000
42
next:
0x3100
Node 0
0x3100
17
next:
0x3200
Node 1
0x3200
89
next:
null
Node 2
List Length: 3 |
Read
Traverse
Insert
Delete
Animation Controls
Linked List Operations
Last updated on