Linked Lists

6 min read

Think of a linked list like a treasure hunt. In a treasure hunt, each clue tells you where to find the next clue. Similarly, in a linked list, each piece of data (called a “node”) contains two things:

  1. The actual data (like a number or name)
  2. A pointer/reference to where the next piece of data is located

Real-world analogy: Imagine a train where each car (node) carries passengers (data) and is connected to the next car (pointer).

1. Singly Linked List #

What is it? #

A singly linked list is like a one-way street. You can only move forward from one node to the next.

Structure: #

[Data|Next] -> [Data|Next] -> [Data|Next] -> NULL

Real-world Example: Music Playlist #

Imagine your music playlist where:

  • Each song (node) contains the song name (data)
  • Each song knows which song plays next (pointer)
  • You can only skip forward, not backward

Example Playlist:

"Bohemian Rhapsody" -> "Stairway to Heaven" -> "Hotel California" -> END

Simple Code Example (Python): #

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

class SinglyLinkedList:
    def __init__(self):
        self.head = None
    
    def add_song(self, song_name):
        new_node = Node(song_name)
        if not self.head:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node
    
    def play_playlist(self):
        current = self.head
        while current:
            print(f"Now playing: {current.data}")
            current = current.next

# Usage
playlist = SinglyLinkedList()
playlist.add_song("Bohemian Rhapsody")
playlist.add_song("Stairway to Heaven")
playlist.add_song("Hotel California")
playlist.play_playlist()

Advantages: #

  • Uses less memory than arrays (no need to declare size beforehand)
  • Easy to add/remove elements at the beginning
  • Dynamic size

Disadvantages: #

  • Can’t go backward
  • No random access (can’t jump to middle directly)
  • Uses extra memory for pointers

2. Doubly Linked List #

What is it? #

A doubly linked list is like a two-way street. You can move forward AND backward.

Structure: #

NULL <- [Prev|Data|Next] <-> [Prev|Data|Next] <-> [Prev|Data|Next] -> NULL

Real-world Example: Web Browser History #

Think of your web browser’s back and forward buttons:

  • Each webpage (node) remembers the previous page and next page
  • You can go back to the previous page or forward to the next page

Example Browser History:

Google <- YouTube <-> Facebook <-> Twitter -> (end)

Simple Code Example (Python): #

class DoublyNode:
    def __init__(self, data):
        self.data = data
        self.next = None
        self.prev = None

class DoublyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None
    
    def visit_page(self, page_name):
        new_node = DoublyNode(page_name)
        if not self.head:
            self.head = self.tail = new_node
        else:
            new_node.prev = self.tail
            self.tail.next = new_node
            self.tail = new_node
    
    def go_back(self, current_page):
        # Find current page and go to previous
        current = self.head
        while current and current.data != current_page:
            current = current.next
        
        if current and current.prev:
            return current.prev.data
        return "No previous page"
    
    def go_forward(self, current_page):
        # Find current page and go to next
        current = self.head
        while current and current.data != current_page:
            current = current.next
        
        if current and current.next:
            return current.next.data
        return "No next page"

# Usage
browser = DoublyLinkedList()
browser.visit_page("Google")
browser.visit_page("YouTube")
browser.visit_page("Facebook")

print(browser.go_back("Facebook"))    # Output: YouTube
print(browser.go_forward("YouTube"))  # Output: Facebook

Advantages: #

  • Can traverse in both directions
  • Easy to delete a node (if you have reference to it)
  • Better for implementing undo/redo functionality

Disadvantages: #

  • Uses more memory (extra pointer for previous)
  • More complex to implement
  • Takes more time to insert/delete (need to update two pointers)

3. Circular Linked List #

What is it? #

A circular linked list is like a race track – it goes in a circle with no beginning or end. The last node points back to the first node.

Structure (Singly Circular): #

[Data|Next] -> [Data|Next] -> [Data|Next] -> (back to first node)
     ^                                            |
     |____________________________________________|

Real-world Example: Round-Robin Game #

Think of a card game where players take turns in a circle:

  • Player 1 -> Player 2 -> Player 3 -> Player 4 -> back to Player 1
  • The game continues forever until someone wins

Example Game:

Alice -> Bob -> Charlie -> Dave -> (back to Alice)

Simple Code Example (Python): #

class CircularNode:
    def __init__(self, data):
        self.data = data
        self.next = None

class CircularLinkedList:
    def __init__(self):
        self.head = None
    
    def add_player(self, player_name):
        new_node = CircularNode(player_name)
        if not self.head:
            self.head = new_node
            new_node.next = new_node  # Points to itself
        else:
            # Find the last node
            current = self.head
            while current.next != self.head:
                current = current.next
            
            # Insert new node
            current.next = new_node
            new_node.next = self.head
    
    def play_round_robin(self, rounds):
        if not self.head:
            return
        
        current = self.head
        for i in range(rounds):
            print(f"Round {i+1}: {current.data}'s turn")
            current = current.next

# Usage
game = CircularLinkedList()
game.add_player("Alice")
game.add_player("Bob")
game.add_player("Charlie")
game.add_player("Dave")

game.play_round_robin(8)  # Play 8 rounds

Advantages: #

  • Great for round-robin scheduling
  • Any node can be a starting point
  • Useful for circular buffers

Disadvantages: #

  • Easy to create infinite loops if not careful
  • More complex to detect the end
  • Difficult to find the “last” node

Real-World Use Cases #

1. Music Applications #

  • Singly Linked: Basic playlist (next song only)
  • Doubly Linked: Advanced playlist (previous/next song)
  • Circular: Repeat playlist mode

2. Web Browsers #

  • Doubly Linked: Browser history (back/forward buttons)
  • Singly Linked: Bookmarks list

3. Operating Systems #

  • Circular: CPU task scheduling (round-robin)
  • Doubly Linked: Process management (easy insertion/deletion)

4. Image Viewers #

  • Doubly Linked: Navigate between photos (previous/next)
  • Circular: Slideshow mode (loops back to first image)

5. Undo/Redo Functionality #

  • Doubly Linked: Text editors, image editors
  • Can go back (undo) or forward (redo)

6. Gaming #

  • Circular: Turn-based games (players take turns in order)
  • Singly Linked: Inventory systems

7. Social Media #

  • Singly Linked: News feed (scroll down to see more)
  • Doubly Linked: Chat messages (scroll up/down)

When to Use Each Type #

Use Singly Linked List When: #

  • You only need to move in one direction
  • Memory is limited
  • Simple implementation is preferred
  • Example: Basic todo list, simple queue

Use Doubly Linked List When: #

  • You need to move in both directions
  • Frequent deletion operations
  • Implementing undo/redo features
  • Example: Text editor, browser history

Use Circular Linked List When: #

  • You need to cycle through elements repeatedly
  • Implementing round-robin algorithms
  • Creating circular buffers
  • Example: Game turns, CPU scheduling

Summary #

Linked lists are like different types of transportation systems:

  • Singly Linked: One-way street (can only go forward)
  • Doubly Linked: Two-way street (can go forward and backward)
  • Circular: Race track (goes in a continuous loop)

Each type has its own strengths and is perfect for different situations. Choose the one that best fits your specific needs!

Updated on June 9, 2025