Skip to main content
Programming

Data Structures Every Developer Should Learn

A review of arrays, lists, stacks, queues, hash maps, and trees with implementations.

G

gs_admin

Author & Reviewer

Published

Feb 07, 2026

Read Time

18 min read

main.go
💻
Programming

# Master Class: Core Data Structures Every Software Engineer Must Learn

SEO Meta Description

Learn the essential data structures for software engineering. A detailed guide covering arrays, linked lists, stacks, queues, hash maps, trees, heaps, and graphs with Big-O complexity analysis and code implementations.

---

Introduction

Algorithms manipulate data, and the structure of that data directly impacts execution speed and memory usage. Selecting the wrong data structure can make an application slow, laggy, and resource-heavy. Conversely, selecting the correct data structure can turn an inefficient algorithm into a fast, scalable process.

To build modern, high-performance systems and pass technical engineering interviews, you must master core data structures.

In this master class, we will examine eight essential data structures: Arrays, Linked Lists, Stacks, Queues, Hash Maps, Trees, Heaps, and Graphs. We will analyze their complexities, review real-world use cases, and implement them in clean, production-ready code.

---

Table of Contents

  1. 1. Big-O Complexity Summary Table
  1. 2. Arrays (Contiguous Memory Blocks)
  1. 3. Linked Lists (Referential Chains)
  1. 4. Stacks (Last In, First Out)
  1. 5. Queues (First In, First Out)
  1. 6. Hash Maps (Key-Value Key Lookups)
  1. 7. Binary Trees (Hierarchical Nodes)
  1. 8. Heaps (Priority Binary Trees)
  1. 9. Graphs (Network Node Models)
  1. 10. Solving Common Technical Interview Questions
  1. 11. Performance Optimization Trade-offs
  1. 12. Frequently Asked Questions (FAQs)
  1. 13. Key Takeaways
  1. 14. Related Resources

---

Big-O Complexity Summary Table

Before exploring each structure, let's review their time complexities for common operations:
Data StructureAccessSearchInsertionDeletionSpace Complexity
Array$O(1)$$O(N)$$O(N)$$O(N)$$O(N)$
Linked List$O(N)$$O(N)$$O(1)$$O(1)$$O(N)$
Stack$O(N)$$O(N)$$O(1)$$O(1)$$O(N)$
Queue$O(N)$$O(N)$$O(1)$$O(1)$$O(N)$
Hash Map$O(1)$$O(1)$$O(1)$$O(1)$$O(N)$
Binary Search Tree$O(\log N)$$O(\log N)$$O(\log N)$$O(\log N)$$O(N)$
Graph$O(N)$$O(V + E)$$O(1)$$O(E)$$O(V + E)$

---

Arrays (Contiguous Memory Blocks)

An array is a collection of elements stored in contiguous memory locations. Because memory is contiguous, we can calculate the memory address of any element using its index.

Key Characteristics

  • Constant Time Access: Accessing an element by index takes $O(1)$ time.
  • Expensive Insertion/Deletion: Inserting or deleting elements requires shifting subsequent items in memory, taking $O(N)$ time.

Real-world Use Case

Storing pixel grids in rendering pipelines, lookup lists, or temporary message buffers.

Code Implementation (PHP)

php
123
// Creating a static array structure
$developerStack = ["PHP", "JavaScript", "Python", "Rust"];
echo "First stack item: " . $developerStack[0]; // Output: PHP

---

Linked Lists (Referential Chains)

A linked list is a linear collection of nodes where each node references the next node in the chain. Unlike arrays, nodes are not stored in contiguous memory locations.

Key Characteristics

  • Fast Insertion/Deletion: Inserting or deleting a node requires only updating references, taking $O(1)$ time.
  • Slow Access: Finding a node requires traversing the list from the head, taking $O(N)$ time.

Real-world Use Case

Implementing undo/redo features (via double linked lists), music playlists, or browser history navigation.

Code Implementation (PHP)

php
12345678910111213141516171819202122232425262728293031
class ListNode {
    public function __construct(
        public mixed $data,
        public ?ListNode $next = null
    ) {}
}

class LinkedList {
    private ?ListNode $head = null;

    public function insertAtHead($data): void {
        $newNode = new ListNode($data);
        $newNode->next = $this->head;
        $this->head = $newNode;
    }

    public function display(): void {
        $current = $this->head;
        while ($current !== null) {
            echo $current->data . " -> ";
            $current = $current->next;
        }
        echo "NULL\n";
    }
}

$list = new LinkedList();
$list->insertAtHead("Node 3");
$list->insertAtHead("Node 2");
$list->insertAtHead("Node 1");
$list->display(); // Output: Node 1 -> Node 2 -> Node 3 -> NULL

---

Stacks (Last In, First Out)

A stack is a linear collection of elements that follows the LIFO (Last In, First Out) principle. The last element added to the stack is the first one removed.

Key Characteristics

  • Push: Adds an item to the top of the stack ($O(1)$ time).
  • Pop: Removes the top item from the stack ($O(1)$ time).
  • Peek: Returns the top item without removing it ($O(1)$ time).

Real-world Use Case

Compiler call stacks, parsing matching brackets in text editors, or backtracking paths in maze-solving algorithms.

Code Implementation (PHP)

php
12345678910111213141516171819202122
class Stack {
    private array $stack = [];

    public function push($item): void {
        array_push($this->stack, $item);
    }

    public function pop(): mixed {
        if ($this->isEmpty()) {
            throw new Exception("Stack is empty.");
        }
        return array_pop($this->stack);
    }

    public function peek(): mixed {
        return end($this->stack);
    }

    public function isEmpty(): bool {
        return empty($this->stack);
    }
}

---

Queues (First In, First Out)

A queue is a linear collection of elements that follows the FIFO (First In, First Out) principle. The first element added is the first one removed.

Key Characteristics

  • Enqueue: Adds an item to the back of the queue ($O(1)$ time).
  • Dequeue: Removes the front item from the queue ($O(1)$ time).

Real-world Use Case

Background job workers (RabbitMQ, Beanstalkd), print queues, or handling incoming request buffers in web servers.

Code Implementation (PHP)

php
123456789101112131415161718
class Queue {
    private array $queue = [];

    public function enqueue($item): void {
        array_push($this->queue, $item);
    }

    public function dequeue(): mixed {
        if ($this->isEmpty()) {
            throw new Exception("Queue is empty.");
        }
        return array_shift($this->queue); // O(N) in PHP arrays, use SplQueue for O(1) in production
    }

    public function isEmpty(): bool {
        return empty($this->queue);
    }
}

---

Hash Maps (Key-Value Key Lookups)

A hash map (or associative array) stores data in key-value pairs. It uses a Hash Function to map keys to bucket indices in memory.

Key Characteristics

  • Constant Time Operations: Access, insertion, and deletion take $O(1)$ time on average.
  • Collision Resolution: Handling cases where different keys hash to the same bucket index (resolved via chaining or open addressing).

Real-world Use Case

Database indexing, caching layers (Redis), or user session lookup stores.

Code Implementation (Python)

python
12345678
# Simple Hash Map lookup in Python
user_cache = {
    "user_101": {"name": "Alice", "role": "admin"},
    "user_102": {"name": "Bob", "role": "editor"}
}

# Fetching user by key takes O(1) time
print(user_cache.get("user_101")) # Output: {'name': 'Alice', 'role': 'admin'}

---

Binary Trees (Hierarchical Nodes)

A binary tree is a hierarchical structure where each node has at most two children, referred to as the left child and the right child. A Binary Search Tree (BST) enforces that the left child contains values less than the parent node, and the right child contains values greater.

Key Characteristics

  • Efficient Search: Searching in a balanced BST takes $O(\log N)$ time.
  • Height Dependency: If the tree is unbalanced, operations can degrade to $O(N)$ time (solved using self-balancing trees like AVL or Red-Black trees).

Real-world Use Case

HTML DOM layout parsing, directory trees, or database indexes (B-Trees).

Code Implementation (PHP)

php
12345678910111213141516171819202122232425262728293031323334353637383940
class TreeNode {
    public function __construct(
        public int $value,
        public ?TreeNode $left = null,
        public ?TreeNode $right = null
    ) {}
}

class BinarySearchTree {
    private ?TreeNode $root = null;

    public function insert(int $value): void {
        $this->root = $this->insertNode($this->root, $value);
    }

    private function insertNode(?TreeNode $node, int $value): TreeNode {
        if ($node === null) {
            return new TreeNode($value);
        }
        if ($value < $node->value) {
            $node->left = $this->insertNode($node->left, $value);
        } else {
            $node->right = $this->insertNode($node->right, $value);
        }
        return $node;
    }

    public function search(int $value): bool {
        return $this->searchNode($this->root, $value);
    }

    private function searchNode(?TreeNode $node, int $value): bool {
        if ($node === null) return false;
        if ($node->value === $value) return true;
        if ($value < $node->value) {
            return $this->searchNode($node->left, $value);
        }
        return $this->searchNode($node->right, $value);
    }
}

---

Heaps (Priority Binary Trees)

A heap is a specialized binary tree that satisfies the Heap Property:
  • Max-Heap: The value of each node is greater than or equal to the values of its children. The highest value is always at the root.
  • Min-Heap: The value of each node is less than or equal to the values of its children. The lowest value is always at the root.

Key Characteristics

  • Priority Fetching: Fetching the max or min element takes $O(1)$ time.
  • Heapify Operations: Inserting or deleting elements takes $O(\log N)$ time.

Real-world Use Case

Priority queues, task scheduling algorithms (CPU scheduling), or finding the shortest path (Dijkstra's algorithm).

---

Graphs (Network Node Models)

A graph is a non-linear data structure consisting of Vertices (Nodes) connected by Edges (Links). Graphs can be directed or undirected, weighted or unweighted.

Key Characteristics

  • Adjacency Representation: Represented using an Adjacency Matrix (2D array) or an Adjacency List (array of lists).
  • Traversal Algorithms: Traversed using Breadth-First Search (BFS) or Depth-First Search (DFS).

Real-world Use Case

Social networks (Facebook friends connection maps), navigation systems (Google Maps routing), or recommendation engines.

Code Implementation (PHP)

php
12345678910111213141516171819202122232425
class Graph {
    private array $adjacencyList = [];

    public function addVertex(string $vertex): void {
        if (!isset($this->adjacencyList[$vertex])) {
            $this->adjacencyList[$vertex] = [];
        }
    }

    public function addEdge(string $v1, string $v2): void {
        $this->addVertex($v1);
        $this->addVertex($v2);
        $this->adjacencyList[$v1][] = $v2;
        $this->adjacencyList[$v2][] = $v1; // Undirected Graph
    }

    public function getNeighbors(string $vertex): array {
        return $this->adjacencyList[$vertex] ?? [];
    }
}

$graph = new Graph();
$graph->addEdge("A", "B");
$graph->addEdge("A", "C");
print_r($graph->getNeighbors("A")); // Output: Array ( [0] => B [1] => C )

---

Solving Common Technical Interview Questions

Challenge: Valid Parentheses (Matching Brackets)

> *Given a string containing brackets (), {}, [], determine if the input string is valid.*

We can solve this efficiently in $O(N)$ time using a Stack:

php
123456789101112131415161718192021
function isValidParentheses(string $s): bool {
    $stack = [];
    $map = [
        &#039;)' => '(',
        &#039;}' => '{',
        &#039;]' => '['
    ];

    for ($i = 0; $i < strlen($s); $i++) {
        $char = $s[$i];
        if (in_array($char, [&#039;(', '{', '['])) {
            array_push($stack, $char);
        } elseif (array_key_exists($char, $map)) {
            if (empty($stack) || array_pop($stack) !== $map[$char]) {
                return false;
            }
        }
    }

    return empty($stack);
}

---

Performance Optimization Trade-offs

  • Time vs. Space Complexity: Using a hash map to speed up lookups (e.g. from $O(N)$ to $O(1)$) requires additional memory to store keys and values. This is known as a Time-Space Trade-off.
  • Array vs. Linked List: Arrays are fast for random access but slow for insertions. Linked lists are fast for insertions but slow for random access. Choose the structure that matches your application's access patterns.

---

Frequently Asked Questions (FAQs)

What is a hash collision?

A collision occurs when two different keys hash to the same index in a hash map. This is resolved using Chaining (storing colliding elements in a linked list at that index) or Open Addressing (searching for the next empty slot in the map).

When should I use a Binary Search Tree instead of a Hash Map?

Use a Hash Map when you only need $O(1)$ key lookups. Use a Binary Search Tree when you need to maintain data in sorted order, or perform range queries (e.g., finding all values between 10 and 50).

---

Key Takeaways

  1. 1. Arrays vs. Linked Lists: Use arrays for fast index access; use linked lists for fast insertions at the head.
  1. 2. Stacks and Queues: Use stacks for LIFO backtracks; use queues for FIFO buffers.
  1. 3. Hash Maps: Provide average $O(1)$ lookup times.
  1. 4. Trees and Graphs: Use BSTs for sorted hierarchies; use graphs to represent connected networks.

---

  • *Introduction to Algorithms* (CLRS) by Thomas H. Cormen
  • *Algorithms* by Robert Sedgewick and Kevin Wayne
G

About the Author: gs_admin

A senior technical contributor specializing in architectural designs, software optimization, database structures, and developer education. Passionate about writing clean code and sharing engineering knowledge.