COMPUTER ENGINEER

← BlogDATA STRUCTURES / ALGORITHMSPython example pack ↓

Linear structures and hashing · 09 / 53

Singly, doubly and circular linked lists

Understand → trace → implement → justify

2 min reading · allow extra time for practice

Linked nodes hold values and links. Singly linked lists have next; doubly linked lists add prev. A circular list ends by revisiting its start rather than encountering None. Sentinel nodes simplify boundaries but are not user data.

Insertion after a known node changes two links. Deleting a singly linked node generally requires its predecessor; knowing only the target is not always sufficient. Doubly linked deletion is O(1) when neighbours are known. Head and tail consistency belong to every operation's invariant.

Memory overhead includes pointers, allocation metadata and fragmentation; locality often loses to arrays. Floyd's two-speed traversal detects cycles. When reversing links, save the old next before overwriting it or the rest of the chain is lost.

A worked trace

Reversing A→B→C starts with prev=None, cur=A and saved nxt=B. Set A.next=None, advance prev and cur. The reversed prefix and untouched suffix remain valid.

Cost and assumptions

Search/index Θ(n); relinking known neighbours O(1); reverse Θ(n) time and O(1) auxiliary space.

Executable example

Run with Python 3. Assertions check a small example; they do not constitute a general correctness proof. Some advanced examples are explicitly small models or reference oracles, not full production implementations.

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

def reverse(head):
    prev = None
    while head is not None:
        nxt = head.next
        head.next = prev
        prev, head = head, nxt
    return prev
head = reverse(Node(1, Node(2, Node(3))))
assert (head.value, head.next.value) == (3, 2)

TEST YOUR UNDERSTANDING

Your turn

Why is while node is not None wrong for a circular list?

Reveal the reasoning

Links never reach None, so traversal never terminates. Compare node identity with the starting node or traverse a known count.

Take it further

  1. Write down the input contract and the invariant before changing the example.
  2. Add empty, boundary, duplicate and adversarial cases where they are relevant. Compare with a simple oracle.
  3. Derive the cost under the stated model; measure several input sizes and explain discrepancies.

Primary reading & lecture notes

Original explanations in this course; these references provide proofs and further reading. Source links may cover the broader module.

Pat Morin · Open Data Structures ↗
Solve the exercise before moving on.