AlgoMaster Logo

Linked List Introduction

High Priority14 min readUpdated June 4, 2026
Listen to this chapter
Unlock Audio

A linked list is one of the fundamental data structures in computer science and a common topic in coding interviews.

Unlike fixed-size arrays, linked lists do not require you to predefine a size. They allocate memory dynamically as elements are added, and because each element points to the next, inserting or removing nodes does not require shifting any data.

This chapter covers:

  • What a linked list is and how it works internally
  • The different types of linked lists
  • The most common linked list operations and their time complexities
  • The interview patterns built around linked lists

What is a Linked List?

A linked list is a linear data structure made up of nodes.

Loading simulation...

Each node contains two parts:

  1. A value, the actual data you want to store.
  2. A pointer (or reference) to the next node in the sequence.

The last node points to null, indicating end of the list.

Unlike arrays, where all elements are stored together in a single, contiguous block of memory, the nodes in a linked list can be scattered across memory.

Arrays (Contiguous Memory Allocation)

0
1
1000
1
3
1004
2
5
1008
3
7
1012
4
9
1016

Linked List (Dynamic Memory Allocation)

1
1000
3
2016
5
3236
7
1604
9
4412
null

What keeps them connected are those pointers linking one node to the next.

This structure makes linked lists flexible to grow and shrink, and insertions or deletions do not require shifting large chunks of memory like arrays do.

But this flexibility comes with a trade-off.

  • Since the elements aren't stored together, you can't jump directly to a specific item like you can with arrays.

Instead, to access the 5th or 10th element, you may have to traverse the list from the beginning, one node at a time, which takes linear time.

Types of Linked Lists

Linked lists come in three common variants, distinguished by how the nodes are connected:

  • Singly linked lists
  • Doubly linked lists
  • Circular linked lists

1. Singly Linked List

In a singly linked list, each node contains a value and a pointer to the next node.

You can only move in one direction, from the head toward the tail.

  • It's simple to implement and memory-efficient.
  • But there's a downside: if you need to go backwards, there's no easy way. You'd have to start from the head and traverse again until you reach the previous node.

Singly linked lists work well when only forward traversal is needed.

2. Doubly Linked List

A doubly linked list takes things one step further.

Each node has two pointers:

  • One pointing to the next node
  • One pointing to the previous node

This means you can move forward and backward, which makes certain operations much more efficient.

But the trade-off is that it uses extra memory to store the additional pointer and it introduces a bit more complexity in updating links during insertions or deletions.

Doubly linked lists are widely used in real-world systems like: LRU caches, text editors for undo/redo functionality, and browser history navigation.

3. Circular Linked List

A circular linked list is a variation where the last node points back to the first node, instead of null.

This forms a loop. You can start at any node and keep going until you're back where you started.

Circular linked lists fit problems with cyclical behavior, such as round-robin scheduling or multiplayer games where turns cycle through players.

Operations on Linked Lists

The most common operations on a linked list are traversal, search, insertion, and deletion.

1. Traversal

Traversal means moving through the list, visiting each node one by one. You start at the head and move one node at a time.

This operation takes O(n) time because, in the worst case, you might visit every node.

If you want to find whether a value exists in a linked list, you must:

  • Start at the head
  • Check each node one by one until you find the value or reach the end

Since this is a linear search, it takes O(n) time in the worst case.

3. Insertion

Linked lists are well-suited to insertion because no shifting is required, unlike with arrays.

There are different cases depending on where you are inserting a node:

Insert at the Beginning

This is the fastest case.

All you need to do is:

  • Create a new node
  • Point its next to the current head
  • Update the head to the new node

It takes constant time since no traversal is needed.

Insert at the End

To insert at the end, you have to:

  • Start at the head
  • Traverse the list until you reach the last node
  • Update the last node's next to the new node

If you maintain a tail pointer, you can insert in constant time O(1). Otherwise, you'll need to traverse the entire list to find the last node, which takes O(n) time.

Insert at a Given Position

To insert at a specific position (say after the 5th node), you must:

  • Traverse to that position
  • Adjust the pointers to insert the new node

Again, this requires O(n) time in the worst case.

4. Deletion

Like insertion, deletion can also vary based on position.

Delete from the Beginning

This is fast. Just move the head pointer to the next node:

This is constant time since no traversal is needed.

Delete from the End or Middle

To delete the last node or a node in the middle:

  • You have to find the previous node
  • Update its next pointer to skip the node you want to delete

Since there's no backward pointer in a singly linked list, this means traversing from the head, which takes O(n) time.

Here's a summary of the time complexities of various operations in a linked list:

Scroll
##### Operation##### Singly Linked##### Doubly Linked (with tail pointer)
TraverseO(n)O(n)
SearchO(n)O(n)
Insert at startO(1)O(1)
Insert at endO(n) without tail, O(1) with tailO(1)
Insert at indexO(n)O(n)
Delete from startO(1)O(1)
Delete from endO(n)O(1)
Delete at indexO(n)O(n)

A few notes on the table:

  • The O(1) cells for insert and delete assume you already have a reference to the relevant node. If you have to search for it first, that lookup itself costs O(n).
  • A singly linked list reaches O(1) insert-at-end only when it maintains a tail pointer alongside head. Without tail, every end insertion has to walk the list.
  • "Delete at index" is O(n) for both variants because the linear cost is in reaching the index, not in unlinking the node once found.

Common Interview Patterns

Three patterns dominate linked-list interview questions: fast and slow pointers, in-place reversal, and dummy nodes.

1. Fast and Slow Pointers

This pattern, also known as Floyd's Tortoise and Hare algorithm, uses two pointers that move through the list at different speeds:

  • The slow pointer advances one node per step.
  • The fast pointer advances two nodes per step.

Because the fast pointer covers twice the distance, the two pointers have a fixed speed difference. This difference is what makes the pattern useful for problems where you need to detect a relationship between two positions in the list without a second pass.

Use case 1: Finding the middle of a linked list

When the fast pointer reaches the end (either null or the last node), the slow pointer is at the midpoint. The intuition is that the fast pointer moves twice as far in the same number of steps, so by the time it has covered the full length, the slow pointer has covered half.

For a list 1 → 2 → 3 → 4 → 5, after three iterations: slow is at 3 and fast is at 5, so slow correctly points to the middle. For an even-length list 1 → 2 → 3 → 4, this returns the second middle (3); a small tweak to the loop condition returns the first middle instead.

Use case 2: Cycle detection

If a linked list has a cycle, the fast pointer keeps lapping inside the loop. Each iteration, the gap between fast and slow closes by exactly one node. Sooner or later they land on the same node.

If there's no cycle, the fast pointer hits null and the loop exits. If there is a cycle, the two pointers eventually meet inside it.

Both variants run in O(n) time and O(1) extra space, which is the main reason the pattern is so widely used: no hash set, no list copy, no second pass.

2. Linked List In-Place Reversal

Reversing a linked list flips the direction of every next pointer, so the original head becomes the new tail and the original tail becomes the new head. The trick is to do this without using extra memory.

The algorithm maintains three pointers as it walks the list once:

  • prev: the node that was before curr (starts as null).
  • curr: the node currently being processed (starts as head).
  • next: the node after curr, saved before we overwrite curr.next.

At each step we flip curr.next to point to prev, then shift all three pointers one step forward.

Tracing through 1 → 2 → 3 → null:

Scroll
StepprevcurrnextPointer state
Startnull11 → 2 → 3 → null
After iter 11221 → null, 2 → 3 → null
After iter 22332 → 1 → null, 3 → null
After iter 33nullnull3 → 2 → 1 → null

The loop exits when curr becomes null, leaving prev at the new head (3). The whole operation is O(n) time and O(1) space.

Reversal shows up directly in problems like Reverse Linked List, and as a sub-step in Palindrome Linked List, Reverse Nodes in k-Group, and Reorder List.

3. Dummy Nodes

A dummy node is a placeholder inserted before the real head of the list. It holds no useful data; its only purpose is to give the algorithm a uniform anchor so that the head is never a special case.

The pattern is useful whenever the head of the list can change during the operation, which is exactly when off-by-one bugs tend to creep in.

Without a dummy node, removing the head requires special-case code:

With a dummy node, the head is no longer special:

Notice three things:

  • The "special case" branch is gone.
  • We return dummy.next instead of head, which automatically handles the case where the original head was removed.
  • The pointer curr starts at dummy, one step behind the real head, so it can uniformly inspect curr.next regardless of whether the head changes.

Dummy nodes are useful for any operation that may modify the head: insertion at the front, merging two sorted lists, removing the nth node from the end, removing duplicates, and partitioning a list around a value.

Those are the three patterns that come up most often in linked-list interview questions.

Quiz

Introduction Quiz

10 quizzes