DEV Community

Cover image for A Comprehensive Guide to Linked Lists: The Flexible Data Structure
Homayoun Mohammadi
Homayoun Mohammadi

Posted on

A Comprehensive Guide to Linked Lists: The Flexible Data Structure

In the realm of data structures, while arrays are often the first tool developers reach for, Linked Lists stand as the second most commonly used structure for solving a wide array of problems. They elegantly address many limitations inherent in arrays and serve as the fundamental building block for more complex data structures like stacks, queues, and graphs.

Unlike static arrays, a linked list is a dynamic data structure that can automatically grow and shrink as needed, providing unparalleled flexibility in memory management.

Image of Linked List

What is a Linked List?

A linked list is a linear data structure consisting of a sequence of elements called nodes. Each node contains two pieces of information:

  1. Value: The actual data being stored.
  2. Pointer (or Link): The memory address of the next node in the sequence.

This chain of nodes forms the list. The first node is called the HEAD, and the last node, which points to null, is called the TAIL.

Key Operations and Runtime Complexity

If you don't understand the performance metrics below, don't worry just click here.

The efficiency of operations on a linked list is a critical consideration. The following table outlines the common Big O time complexities:

Operation Description Complexity
Lookup By Value O(n)
By Index O(n)
Insert At the Beginning O(1)
At the End O(1) *
In the Middle O(n)
Delete From the Beginning O(1)
From the End O(n) *
From the Middle O(n)

Linked Lists in Code: A Java Example

Java provides a built-in LinkedList class in its Collections framework, which is actually a implementation of a doubly linked list. Here's a simple demonstration:

import java.util.LinkedList;

public class Main {
    public static void main(String[] args) {
        // Create a new linked list to store integers
        LinkedList<Integer> list = new LinkedList<>();

        // Add elements to the end of the list
        list.addLast(10);
        list.addLast(20);
        list.addLast(30);

        // Add an element to the beginning
        list.addFirst(5);

        // Print the size and the contents of the list
        System.out.println("Size: " + list.size()); // Output: 4
        System.out.println("List: " + list); // Output: [5, 10, 20, 30]
    }
}
Enter fullscreen mode Exit fullscreen mode

Image that at a left is array and in the right side is the linkedlist

Linked Lists vs. Arrays:

  • Arrays: Static arrays have a fixed size, which can lead to wasted memory if too large or a lack of space if too small. Dynamic arrays (like ArrayList in Java) solve the size issue but can waste memory when they grow, as they often allocate a new block that is 50-100% larger and copy the old elements over.
  • Linked Lists: Nodes are allocated individually in memory. They only use the memory required for the current number of elements, plus the overhead of the pointers. There is no wasted, unused pre-allocated space.
  • When to Use Which:
    • Use an array (or ArrayList) if you know the approximate number of items in advance (e.g., you can initialize it with new ArrayList(100)).
    • Use a linked list when you need frequent insertions and deletions at the beginning and end of the list and the size is highly variable.

Performance Overview

The Image blew provides a high-level comparison of the average time complexities for each data structure, highlighting their strengths and weaknesses.

Image that comparing performance of the array with linked list

Types of Linked Lists

There are several common variations of the basic linked list:

1. Singly Linked List

This is the most basic type. Each node points only to the next node in the sequence. The traversal is unidirectional, from head to tail.

Image of Single Linked List

2. Doubly Linked List

In this type, each node has two pointers: one to the next node and one to the previous node. This allows for bidirectional traversal, which makes some operations (like deleting the tail node) more efficient, albeit at the cost of increased memory usage per node.

Image of double linked list

Other types include Circular Linked Lists, where the tail node points back to the head, creating a circle.

Summary and Key Takeaways

  • Purpose: Linked lists are the second most used data structure, ideal for scenarios requiring dynamic sizing and frequent insertions/removals from the ends.
  • Memory: They can grow and shrink automatically, eliminating memory waste but incurring a small overhead for the pointers in each node.
  • Performance:
    • Strengths: Excellent performance for adding/removing elements at the beginning (O(1)).
    • Weaknesses: Poor performance for lookups (O(n)) as they require sequential access.

Understanding the trade-offs between linked lists and arrays is fundamental to choosing the right tool for the job and writing efficient, effective software.

Top comments (2)

Collapse
 
homayoun_mohammadi_2cbc42 profile image
Homayoun Mohammadi

Continue this DSA series these are great

Collapse
 
homayunmmdy profile image
Homayoun Mohammadi

Okay I will do that