Interactive Learning

Data Structures &
Algorithms

Master the building blocks of efficient programming. Visualize, interact, and understand core concepts through minimalist design and clear explanations.

Start Learning

Time Complexity Overview

Understanding Big O notation is crucial for analyzing algorithm efficiency. Lower is better.

O(1)

Constant Time

Execution time stays the same regardless of input size. The holy grail of algorithms.

Array Access Hash Map
O(log n)

Logarithmic

Doubling the input barely increases runtime. Highly efficient for large datasets.

Binary Search BST Ops
O(n)

Linear Time

Runtime grows proportionally with input size. Acceptable for most operations.

Linear Search Array Traversal
O(n²)

Quadratic

Performance degrades rapidly with larger inputs. Avoid for large datasets.

Bubble Sort Nested Loops
Linear Data Structure

Arrays

The simplest and most widely used data structure. Elements are stored in contiguous memory locations, allowing instant access via index.

Fast Access

O(1) time to access any element by index

Fixed Size

Insertion and deletion are expensive O(n) operations

JavaScript
// Declaration & Initialization
const arr = [10, 20, 30, 40, 50];

// Access (O(1))
console.log(arr[2]); // 30

// Insert at end (O(1))
arr.push(60);

// Search (O(n))
const index = arr.indexOf(30);

Interactive Visualization

Node Structure

Each node contains data and a pointer to the next node
Dynamic Data Structure

Linked Lists

A sequence of nodes where each node points to the next. Unlike arrays, elements are not stored contiguously, allowing efficient insertion and deletion.

O(1)
Insert/Delete
At beginning
O(n)
Search
Linear traversal
Structure
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;  // Pointer to next node
    }
}

class LinkedList {
    constructor() {
        this.head = null;
        this.size = 0;
    }
    
    // O(1) insertion at head
    prepend(data) {
        const newNode = new Node(data);
        newNode.next = this.head;
        this.head = newNode;
    }
}
LIFO

Stack

Last In, First Out. Think of a stack of plates. Operations happen only at the top.

Bottom
// Operations
stack.push(item);  // O(1) - Add to top
stack.pop();       // O(1) - Remove top
stack.peek();      // O(1) - View top

// Use cases: Undo, Browser History, 
// Function Call Stack
FIFO

Queue

First In, First Out. Like a line at a ticket counter. Fair and orderly processing.

Front
// Operations
queue.enqueue(item);  // O(1) - Add to rear
queue.dequeue();      // O(1) - Remove front
queue.front();        // O(1) - View front

// Use cases: Print Spooling, 
// CPU Scheduling, BFS
Hierarchical Structure

Binary Search Trees

A node-based structure where each node has at most two children. Left child is smaller, right child is larger. Enables efficient searching.

Tree Visualization

Properties

  • Left subtree contains only nodes with values lesser than the parent
  • Right subtree contains only nodes with values greater than the parent
  • Both left and right subtrees must also be binary search trees

Complexity

Search O(log n)
Insert O(log n)
Delete O(log n)

* Assuming balanced tree. Worst case O(n) for skewed tree.

class TreeNode {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

// Inorder traversal
// Left -> Root -> Right
// Gives sorted order

Sorting Algorithms

Visual comparison of different sorting approaches. Click to see them in action.

Bubble Sort

Repeatedly steps through the list, compares adjacent elements and swaps them if they are in the wrong order.

O(n²) Simple

Quick Sort

Divide and conquer algorithm. Picks an element as pivot and partitions the array around it.

O(n log n) Efficient

Merge Sort

Divides the array into halves, sorts them and then merges them back together.

O(n log n) Stable