DocsHub
Linked Lists

Singly Linked List

Build a singly linked list from scratch and learn how to insert, delete, and traverse it.

Singly Linked List

A singly linked list is the simplest form. Each node has a value and one pointer — next — pointing to the next node. You can only move forward through the list.

Singly Linked Liststep-through
head
val
10
next
val
20
next
val
30
next
val
40
next
val
50
next
None
singly_linked.py
def prepend(value):
new_node = Node(value)
new_node.next = self.head
self.head = new_node
prepend(5) — add to beginning
step 0/3
0%

Full implementation

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


class SinglyLinkedList:
    def __init__(self):
        self.head = None
        self.size = 0

    def append(self, value):
        """Add to the end — O(n)"""
        new_node = Node(value)
        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 prepend(self, value):
        """Add to the beginning — O(1)"""
        new_node = Node(value)
        new_node.next = self.head
        self.head = new_node
        self.size += 1

    def insert_at(self, index, value):
        """Insert at a specific index — O(n)"""
        if index == 0:
            self.prepend(value)
            return
        new_node = Node(value)
        current = self.head
        for _ in range(index - 1):
            if not current:
                raise IndexError("Index out of range")
            current = current.next
        new_node.next = current.next
        current.next = new_node
        self.size += 1

    def delete_head(self):
        """Remove from beginning — O(1)"""
        if not self.head:
            return None
        value = self.head.value
        self.head = self.head.next
        self.size -= 1
        return value

    def delete_at(self, index):
        """Remove at a specific index — O(n)"""
        if index == 0:
            return self.delete_head()
        current = self.head
        for _ in range(index - 1):
            if not current.next:
                raise IndexError("Index out of range")
            current = current.next
        value = current.next.value
        current.next = current.next.next
        self.size -= 1
        return value

    def search(self, value):
        """Find index of value — O(n)"""
        current = self.head
        index = 0
        while current:
            if current.value == value:
                return index
            current = current.next
            index += 1
        return -1

    def to_list(self):
        result = []
        current = self.head
        while current:
            result.append(current.value)
            current = current.next
        return result

How insert at beginning works — O(1)

Before:  head → [10] → [20] → [30] → None

Step 1 — create new node:
         new → [5] → None

Step 2 — new.next = head:
         new → [5] → [10] → [20] → [30] → None

Step 3 — head = new:
head → [5] → [10] → [20] → [30] → None

Just two pointer reassignments. No elements move. O(1).


How delete at position works — O(n)

Delete index 2 from: [10] → [20] → [30] → [40] → None

Step 1 — walk to node before target (index 1):
current = [20]

Step 2 — bypass the target:
current.next = current.next.next

Result: [10] → [20] → [40] → None
        [30] is now unreachable — garbage collected

Reversing a linked list

A classic interview problem:

def reverse(self):
    prev = None
    current = self.head

    while current:
        next_node = current.next   # save next
        current.next = prev        # reverse pointer
        prev = current             # move prev forward
        current = next_node        # move current forward

    self.head = prev

The reversal uses three pointers — prev, current, and next_node. At each step, reverse the current pointer, then advance both prev and current. When current becomes None, prev is the new head.


Complexity

OperationTimeSpace
PrependO(1)O(1)
AppendO(n)O(1)
Insert at indexO(n)O(1)
Delete headO(1)O(1)
Delete at indexO(n)O(1)
SearchO(n)O(1)
TraverseO(n)O(1)

On this page