Algo rithms

Recipes for
Computation

An algorithm is an unambiguous specification of how to solve a class of problems. It can perform calculation, data processing, and automated reasoning tasks. This guide visualizes the internal logic of these digital engines.

01 / Bringing Order

Sorting Algorithms

Sorting organizes data to make subsequent retrieval (searching) efficient.

Compare
Swap/Active
Sorted
Select a method.

Understanding the Mechanics

Bubble Sort (O(n²))

Think of air bubbles rising to the surface. In each pass, adjacent elements are compared. If they are in the wrong order (e.g., 5 then 2), they are swapped. The largest unsorted element "bubbles up" to its correct position at the end of the list with each full iteration. It is simple to implement but extremely inefficient for large datasets.

Selection Sort (O(n²))

This algorithm divides the list into a "sorted" left side and an "unsorted" right side. It scans the entire unsorted side to find the fewer swaps than Bubble Sort but the same number of comparisons.

Insertion Sort (O(n²))

Analogous to sorting playing cards in your hand. You pick up one card at a time from the unsorted pile and slide it into its correct or lists that are already mostly sorted.

Merge Sort (O(n log n))

A "Divide and Conquer" powerhouse. It recursively splits the list in half until every sub-list contains only one element (which is inherently sorted). Then, it merges these sub-lists back together in sorted order. It is mathematically guaranteed to be fast and stable (preserves order of duplicates).

Quick Sort (O(n log n))

Also "Divide and Conquer", but works in-place. It picks a "pivot" element and partitions the array so that all smaller elements are to the left and all larger elements are to the right. It then recursively sorts the sub-arrays. It is often the fastest sorting algorithm in practice, though a bad pivot choice can slow it down.

Heap Sort (O(n log n))

Uses a Binary Heap data structure. It divides the input into sorted and unsorted regions, and iteratively shrinks the unsorted region by extracting the largest element and moving that to the sorted region. It is efficient and requires minimal extra space.

Counting Sort (O(n + k))

A non-comparative sorting algorithm. It counts the number of objects having distinct key values (like hashing). Then it does some arithmetic to calculate the position of each object in the output sequence. It is efficient when the range of input values (k) is not significantly greater than the number of objects (n).

Bogo Sort (O((n+1)!))

Also known as "Stupid Sort" or "Monkey Sort". It simply shuffles the array randomly and checks if it's sorted. It exists solely as a warning against inefficiency.

02 / Divide & Conquer

Searching Algorithms

Select method & number.

The Power of Structure

Linear Search (O(n)): The simplest method. You look at every item one by one until you find what you need. It works on any list, sorted or not, but is inefficient for large datasets.

Binary Search (O(log n)): This algorithm fundamentally relies on the data being sorted. By checking the middle element, it can instantly discard half of the remaining possibilities. If you are looking for a name in a phone book of 1,000,000 people, Linear Search might take 1,000,000 steps. Binary Search takes at most 20 steps (log₂ 1,000,000 ≈ 20).

Hash Table (O(1)): The fastest search method. It uses a hash function to map keys to values directly, allowing for average constant-time lookups, unlike scanning an array.

03 / Number Theory

Euclid's Algorithm (GCD)

Enter numbers to visualize GCD
Ready.

Ancient & Elegant

The Principle: The Greatest Common Divisor (GCD) of two numbers doesn't change if you replace the larger number with the difference (or modulo). GCD(A, B) = GCD(B, A % B).

Visualization: Using the "subtraction" method involves cutting rectangles. If you have a rectangle of 48x18, you can cut off two 18x18 squares, leaving a 12x18 rectangle. Then cut 12x12, leaving 12x6. Finally two 6x6 fit perfectly. Square size 6 is the GCD.

04 / Disjoint Sets

Union-Find

Ready.

Connectivity & Cycles

Union-Find (or Disjoint-Set Union / DSU) keeps track of elements partitioned into disjoint sets. It's incredibly fast (nearly constant time `O(α(n))`) for two operations:
1. Union: Merge two sets.
2. Find: Determine which set an element belongs to.

It is widely used in network connectivity, image processing, and Kruskal's Algorithm for Minimum Spanning Trees.

05 / The Stack

Recursion

Memory Stack
function fact(n) {
  if (n <= 1) return 1;
  return n * fact(n-1);
}
Ready.

Self-Referential Logic

Concept: Recursion is a method where the solution to a problem depends on solutions to smaller instances of the same problem. It consists of a Base Case (when to stop) and a Recursive Step (breaking the problem down).

The Call Stack: Computers handle function calls using a "Stack". When fact(3) calls fact(2), it doesn't finish immediately; it pauses and adds a new "frame" to memory. Only when the base case is reached do the frames "pop" off, passing values back up the chain. If you forget the base case, you get the infinite loop known as a Stack Overflow.

06 / Trial & Error

Backtracking: N-Queens

function solve(row) {
  if (row >= 4) return true;
  for (col = 0 to 3) {
    if (isValid(row, col)) {
      board[row] = col;
      if (solve(row + 1)) return true;
      board[row] = -1; // Backtrack
    }
  }
  return false;
}
Ready.

Constraint Satisfaction

Concept: Backtracking is an algorithmic-technique for solving problems recursively by trying to build a solution incrementally, one piece at a time, removing those solutions that fail to satisfy the constraints of the problem at any point of time.

In Action: In the N-Queens problem, the algorithm places a Queen in the first available column of the current row. It then moves to the next row. If it finds it cannot place a Queen anywhere in the new row without being attacked, it realizes the previous placement was a mistake. It "backtracks" (returns) to the previous row, moves that Queen to a new spot, and tries again.

07 / Traversal

Pathfinding

Drag nodes to rearrange • Click weight to edit • Click Start
Visited: 0
Cost: 0
Edit Edge Weight

⚠️ Enter weight less than 50

Exploring Graphs

BFS (Breadth-First Search): Uses a Queue (FIFO). It radiates out from the starting node level by level. Guaranteed to find the shortest path (fewest edges) in an unweighted graph.

DFS (Depth-First Search): Uses a Stack (LIFO). It plunges deep into one path before backtracking. It doesn't find the shortest path but is useful for exploring all connected components.

Dijkstra's Algorithm: Uses a Priority Queue based on path cost. It excels in Weighted Graphs (where edges have different lengths/costs). It always finds the absolute lowest-cost path.

A* Search (A-Star): A smart search that uses a Heuristic (Euclidean distance here). It prioritizes nodes physically closer to the target, often finding the path much faster.

08 / Compression

Huffman Coding

A popular algorithm for lossless data compression. It assigns shorter binary codes to more frequent characters.

1. Frequency

2. Code Table

Run to generate...

3. Optimal Tree Construction

Calculation Log

Waiting for input...

4. Result

Ready.

5. Efficiency Stats

Original Size: - Compressed Size: - Compression Ratio: -

Deep Dive: Why it works

1. Variable Length Codes: In ASCII, every character is 8 bits (e.g., 'a' is 01100001). Huffman uses variable lengths. Frequent characters like 'e' or 's' might get just 2 or 3 bits, while rare ones get longer codes.

2. The Prefix Property: Notice that no code is a prefix of another. If 'a' = 0, then 'b' cannot be 01, because the decoder wouldn't know if "01" is "a" followed by "1" or just "b". By ensuring this property (via the tree structure), we don't need separators between codes.

3. Greedy Strategy: The algorithm is "greedy" because at each step, it makes the locally optimal choice: it merges the two smallest probability nodes. This simple local rule guarantees a globally optimal tree for the entire message.

09 / Optimization Strategies

Knapsack Problem (0/1)

The Challenge: Capacity 10kg. Maximize Value.

Weight: 0 / 10kg Total Value: $0
Ready to pack.

Greedy vs. Dynamic Programming

The Greedy Flaw: A greedy strategy picks the item with the highest value-to-weight ratio first. In the example above, it picks the 6kg/$90 item. This fills the bag so much (6/10kg) that it cannot fit the next best items (5kg/$70). It ends up with $100 total.

The DP Solution: Dynamic Programming breaks the problem down. It effectively asks: "For a capacity of X kg, is it better to take this item or leave it?" It checks every combination mathematically. It realizes that skipping the high-ratio 6kg item allows us to take two 5kg items, resulting in $140 total.

10 / NP-Hard

Traveling Salesman Problem

Visualization Key: Gray Dashed = Testing Path. Pink Solid = Best Path.

Current Check: 0
Best Dist: -

Combinatorial Explosion

The Problem: Given a list of cities, find the shortest route that visits each city exactly once and returns to the origin city.

Why it's Hard: There is no known fast algorithm for this. We must use Brute Force (checking every permutation). For 5 cities, there are only (5-1)! / 2 = 12 unique routes. But for 20 cities, there are 60 quadrillion routes. This is an NP-Hard problem.

11 / Greedy Approach

Coin Change

25
10
5
1
Coins will appear here
Enter amount.

Greedy vs. Optimal

For canonical coin systems (like US Dollars: 1, 5, 10, 25), a Greedy algorithm (always taking the largest coin possible) is guaranteed to produce the optimal solution (fewest coins). However, for arbitrary systems (e.g., coins 1, 3, 4), Greedy fails. To make 6, Greedy would choose 4+1+1 (3 coins), while the optimal is 3+3 (2 coins).

12 / Memoization

Fibonacci DP

Cache empty.

Trading Space for Time

Naive recursion for Fibonacci is O(2ⁿ) because it recalculates the same values over and over (e.g., calculating Fib(5) requires Fib(3) multiple times). This is known as Overlapping Subproblems. Memoization stores these results in a table (cache) the first time they are computed. This reduces the time complexity to O(n) at the cost of O(n) memory space.

13 / Performance Analysis

Time & Space Complexity

10 items
O(1) & O(log n)Instant
O(n)Linear
O(n²)Quadratic
O(2ⁿ)Exponential

Space vs Time

Big O Notation: A mathematical notation that describes the limiting behavior of a function. It classifies algorithms according to how their run time or space requirements grow as the input size grows.

Space Complexity: Algorithms don't just consume time; they consume memory.
In-Place (O(1)): Algorithms like Bubble Sort and Insertion Sort reorder elements within the original array, requiring almost no extra memory.
Linear Space (O(n)): Merge Sort creates new sub-arrays to perform the merge step, requiring memory proportional to the dataset size.
Recursion Stack: Recursive algorithms use memory for the Call Stack. Depth matters.

Glossary

Key Definitions

Algorithm

An unambiguous specification of how to solve a class of problems.

Sorting

Organizing data to make subsequent retrieval (searching) efficient.

Big O Notation

A mathematical notation that describes the limiting behavior of a function (complexity).

Recursion

A method where the solution involves solving smaller instances of the same problem.

Backtracking

An algorithmic-technique for solving problems recursively by trying to build a solution incrementally.

Dynamic Programming (DP)

Breaking a problem into simpler subproblems and storing the results to avoid re-computation.

Greedy Algorithm

Making the locally optimal choice at each stage with the intent of finding a global optimum.

Divide and Conquer

Breaking a problem into sub-problems, solving them, and combining the results.

Pathfinding

Finding the shortest route between two points.

Knapsack Problem

A combinatorial optimization problem to maximize value within a weight limit.

14 / Knowledge Check