Skip to content

sumitsingh4411/VisualDSA

Repository files navigation

Visual DSA

Algorithms you can watch run.

44 interactive lessons that teach data structures & algorithms by animating them — from "I've never written code" to A*, Dijkstra and dynamic programming. No account. No paywall. No videos.

Visual DSA


Why this exists

Most DSA resources hand you a wall of text and a finished code block, and expect the algorithm to assemble itself in your head. That works if you can already run code in your head. If you can't, you get stuck — and you conclude you're "bad at algorithms."

You're not. You just can't see it.

Every lesson here starts in plain English with a real-world analogy, then lets you watch the algorithm execute, one step at a time, at your own pace, on your own numbers. The code highlights the line it's running. The variables show what it's holding in its head. A plain sentence explains each step as it happens.

Nothing is pre-recorded. Every animation is generated by actually running the algorithm.


Run it

git clone https://github.com/sumitsingh4411/VisualDSA.git
cd VisualDSA
npm install
npm run dev          # → http://localhost:3000
npm test             # 613 tests — the engine, every algorithm, the content
npm run typecheck    # strict TypeScript
npm run build        # every page prerenders to static HTML

No database, no API keys, no .env to fill in. It runs offline.


What a lesson gives you

A lesson mid-run

Every one of the 44 lessons has all seven of these — none are stubs:

Start here The idea in plain English, written for someone who has never coded
Picture it A real-world analogy before any code appears
Watch it run The interactive visualization — play, pause, step, scrub, and type your own input
What it costs Big-O, with a chart of how it actually grows
Common traps The mistakes people really make (off-by-one, the <=, the missing base case)
Check yourself A quiz that explains why, right or wrong
Practice Hand-picked LeetCode problems that use exactly this technique

The code panel shows JavaScript, Python, Java and C++, all four lined up line-for-line — and the highlighted line follows the animation no matter which tab you pick.


What you'll learn

44 lessons · 8 levels · ~7.5 hours · 1,139 animation steps

Level 1 — Foundations

The row of boxes everything is built on.

Lesson The idea
Arrays & Memory The row of numbered boxes that everything else is built on
Strings A string is an array of characters. Everything else follows
2D Arrays The grid is a fiction. Memory is one flat line — and that's why row-major is fast
Hash Map Turn a key straight into a location — the structure behind almost everything
Sets A hash map that threw away the values — "seen this before?", instantly

Level 2 — Searching

Finding one thing among many — the slow honest way, then the fast clever way.

Lesson The idea
Linear Search Check every box until you find it. Simple, honest, slow
Binary Search Throw away half the list with every single question
Ternary Search Cut into thirds instead of halves — and discover it's actually slower

Level 3 — Sorting

Putting things in order, and discovering that how you do it matters enormously.

Lesson The idea
Bubble Sort Compare neighbours, swap if wrong. Repeat until calm
Selection Sort Find the smallest. Put it in front. Repeat
Insertion Sort How you actually sort a hand of cards, without being taught
Merge Sort Split until it's trivial, then merge back in order
Quick Sort Pick a pivot, split around it, let the halves sort themselves
Heap Sort Turn the array into a heap, then keep taking the biggest off the top
Shell Sort Insertion sort, but values may leap instead of crawl
Counting Sort Sorts without comparing anything — that's how it beats n log n
Radix Sort Sort by the last digit first. It sounds backwards, and it's the only way it works

Level 4 — Linear structures

Two structures that differ by one decision — and become completely different tools.

Lesson The idea
Stack Last in, first out. The undo button of data structures
Queue First in, first out. Fairness, as a data structure
Deque A queue open at both ends — a stack and a queue in one
Circular Queue A queue in a fixed array that never shuffles — the pointers go round instead

Level 5 — Linked structures

Giving up instant access to buy cheap insertion. The first real trade-off.

Lesson The idea
Linked List No shelves, no addresses — just a chain of notes saying "next"
Doubly Linked List One extra pointer per node — and the singly linked list's worst flaw disappears
Circular Linked List The tail points back at the head. There is no end — and that's the point

Level 6 — Trees

When a list isn't enough and your data starts to branch.

Lesson The idea
Binary Search Tree Keeps one promise — smaller left, bigger right — so it can search fast
Tree Traversals Three ways to visit every node — and why the order matters
Heap & Priority Queue A tree that always keeps the biggest thing on top, ready to grab
AVL Tree A search tree that refuses to become a list — it rotates itself level again
Segment Tree Every node stores the answer for a whole range — so a range query stops early
Trie Words that start the same share the same path — so autocomplete is free

Level 7 — Graphs

Anything connected to anything: maps, friendships, the internet itself.

Lesson The idea
Breadth-First Search Explore a network in rings, nearest first — using a queue
Depth-First Search Plunge down one path to the end, then back up and try the next
Topological Sort Put jobs in an order where nothing happens before what it depends on
Dijkstra's Shortest Path The cheapest route through a weighted map — always finish the nearest place first
Bellman–Ford Slower than Dijkstra, and it can do the one thing Dijkstra can't
A* Search Dijkstra with a sense of direction — it guesses what's left, and aims
Union-Find "Are these two connected?" — in effectively constant time

Level 8 — Core techniques

The moves that unlock the hard problems.

Lesson The idea
Recursion & the Call Stack A function that calls itself — and the pile of calls that piles up
Two Pointers Two markers moving toward each other turn an O(n²) search into O(n)
Sliding Window Reuse the last answer instead of recomputing
Monotonic Stack A stack kept in order — one new value answers many old questions at once
Greedy Algorithms Always take the best-looking option right now — and sometimes that's provably optimal
Backtracking Guess, explore, and when it dead-ends — put it back exactly as it was
Dynamic Programming Solve each small problem once, write the answer down, never solve it again
📊 Big-O cheat sheet — all 44, best / average / worst / space
Algorithm Best Average Worst Space
Arrays & Memory O(1) to read O(n) to insert O(n) to insert O(n)
Strings O(1) index O(n) to scan O(n) to scan O(1)
2D Arrays O(1) to read a cell O(r × c) to scan O(r × c) O(r × c)
Hash Map O(1) O(1) O(n) O(n)
Sets O(1) O(1) O(n) O(n)
Linear Search O(1) O(n) O(n) O(1)
Binary Search O(1) O(log n) O(log n) O(1)
Ternary Search O(1) O(log n) O(log n) O(1)
Bubble Sort O(n) O(n²) O(n²) O(1)
Selection Sort O(n²) O(n²) O(n²) O(1)
Insertion Sort O(n) O(n²) O(n²) O(1)
Merge Sort O(n log n) O(n log n) O(n log n) O(n)
Quick Sort O(n log n) O(n log n) O(n²) O(log n)
Heap Sort O(n log n) O(n log n) O(n log n) O(1)
Shell Sort O(n log n) ≈ O(n^1.3) O(n²) O(1)
Counting Sort O(n + k) O(n + k) O(n + k) O(k)
Radix Sort O(d × n) O(d × n) O(d × n) O(n + b)
Stack O(1) push O(1) pop O(1) peek O(n)
Queue O(1) enqueue O(1) dequeue O(n) if built badly O(n)
Deque O(1) O(1) O(1) O(n)
Circular Queue O(1) O(1) O(1) O(capacity)
Linked List O(1) insert at head O(n) to find O(n) to reach the tail O(n)
Doubly Linked List O(1) delete a known node O(n) to find O(n) to find O(n)
Circular Linked List O(1) insert at head O(n) to find O(n) full lap O(n)
Binary Search Tree O(log n) O(log n) O(n) O(n)
Tree Traversals O(n) O(n) O(n) O(n)
Heap & Priority Queue O(1) O(log n) O(log n) O(n)
AVL Tree O(log n) O(log n) O(log n) O(n)
Segment Tree O(log n) query O(log n) update O(n) to build O(n)
Trie O(L) O(L) O(L) O(total characters)
Breadth-First Search O(V + E) O(V + E) O(V + E) O(V)
Depth-First Search O(V + E) O(V + E) O(V + E) O(V)
Topological Sort O(V + E) O(V + E) O(V + E) O(V)
Dijkstra's Shortest Path O(E log V) O(E log V) O(E log V) O(V)
Bellman–Ford O(E) O(V × E) O(V × E) O(V)
A* Search O(E) O(E log V) O(E log V) O(V)
Union-Find O(1) O(α(n)) O(α(n)) O(n)
Recursion & the Call Stack O(n) O(n) O(n) O(n)
Two Pointers O(1) O(n) O(n) O(1)
Sliding Window O(n) O(n) O(n) O(1)
Monotonic Stack O(n) O(n) O(n) O(n)
Greedy Algorithms O(n log n) O(n log n) O(n log n) O(1)
Backtracking O(n!) O(n!) O(n!) O(n)
Dynamic Programming O(n·k) O(n·k) O(n·k) O(n)

Every row is read from the lesson itself — the table and the site cannot disagree.


Find your way in

Roadmap — the whole curriculum as one winding trail, coloured cool→warm as difficulty rises. Your progress fills it in.

Roadmap

Topics — already know what you want? Search all 44 and jump straight there.

Topics

Problems — 106 hand-picked LeetCode problems, each mapped to the lesson that teaches it. Learn the technique, then go solve it.

Problems

Paths — you've learned DSA, now what? Four honest directions: interviews, competitive programming, ICPC, real-world dev.

Paths


The one idea everything is built on

An algorithm is not an animation. It's a generator that yields immutable snapshots.

Every algorithm is a plain TypeScript generator that yields a Frame at each meaningful step:

type Frame = {
  data;         // the array / tree / graph at this instant
  pointers;     // named cursors: i, low, mid, head
  highlights;   // which index is comparing / swapping / sorted / found
  codeLine;     // which source line is executing right now
  variables;    // what the algorithm is holding in its head
  explanation;  // one plain sentence — this is also the dry-run row
  stats;        // running comparison / swap counts
};

runAlgorithm() drains the generator into a Frame[]. From there, every feature in the UI is just a view over one index into that array:

Feature How it works
play / pause / step / scrub index++, index--, drag the index
the written dry run frames.map(f => f.explanation)
the synced code highlight frames[index].codeLine
live variables & pointers frames[index].variables
the custom-input playground re-run the generator on new input
the timeline "fingerprint" one coloured tick per frame

Because the stage, the code panel, the variables and the walkthrough all read the same index, they can never disagree about which step you're on. That's the whole trick.


Adding a lesson

The architecture exists so new topics are cheap. Three steps, and you never touch a component:

  1. Write the generator in src/lib/algorithms/…. yield a Frame at each step, set codeLine to the matching line of your source and explanation to one plain sentence.
  2. Write a test next to it. Assert the output is correct and that the teaching claim holds — a sort that reports the wrong complexity is a bug in the lesson, not just the code.
  3. Add a content module in src/lib/content/lessons/ implementing Lesson: intro, analogy, four-language code, complexity, common traps, quiz, practice problems. Register it in src/lib/content/index.ts.

The player, controls, dry run, code sync, complexity chart, quiz and playground all light up automatically. Only a genuinely new visual shape costs a component — one file in viz/, one case in viz/Stage.tsx. There are 11 so far: bars, array, stack, queue, list, call stack, tree, trie, graph, grid, hash.


How the tests keep the animations honest

For a teaching tool, the animation must not lie. The generators are pure functions, so the suite asserts the pedagogy directly — not just "did it sort":

  • bubble sort really costs n(n−1)/2 comparisons on reversed input
  • insertion sort really is O(n) on already-sorted input — its entire selling point
  • binary search really finds any value among 1024 items in ≤ 11 looks, while linear search takes 1024
  • Dijkstra really returns A→C→G = 14, not the shorter-looking route
  • no frame ever emits an out-of-range pointer, or a codeLine past the end of its own source

613 tests. If an animation lied, a test would fail.

One honest caveat, learned the hard way: these tests assert frames, not layout. They once passed while every sorting bar silently rendered at zero height, because a CSS percentage had no parent to measure against. Frame correctness is not pixel correctness — open a browser.


Project layout

src/
  lib/engine/          Frame types, runAlgorithm(), usePlayer() state machine
  lib/algorithms/      pure generators — sorting, searching, structures, graphs, DP
  lib/content/         typed lesson modules + the curriculum registry
  components/viz/      one component per data shape; renders a Frame, nothing more
  components/player/   controls, timeline, synced code, variables, dry run
  components/lesson/   lesson sections (analogy, complexity, traps, quiz, playground)
  components/landing/  hero, particle field, the roadmap trail, FAQ
  components/paths/    the post-DSA guides
  store/               Zustand + localStorage: XP, streak, completion, bookmarks

Stack

Next.js 16 (App Router) · React 19 · TypeScript (strict) · Tailwind v4 · Framer Motion · Zustand · Lucide · Vitest

Deliberately not built

No backend, accounts, database, live code execution, AI tutor, audio or PWA. Progress lives in your browser, so there's no signup wall between a curious visitor and their first lesson — the trade-off is that progress is per-device.

These were scoped out on purpose, to spend the effort making the visualizations extraordinary instead. The architecture leaves clean room to add them later.


Deploying

Deployed on Vercel at visualdsa.nextjoblist.com. Import the repo, add the domain, ship — there is nothing to configure. A production build already resolves to that origin, and canonical URLs, sitemap.xml, robots.txt and all Open Graph images derive from it.

Changing the domain later, or deploying your own copy? Either edit PRODUCTION_URL in src/lib/site.ts, or override it without touching code:

NEXT_PUBLIC_SITE_URL=https://your-domain.com npm run build

Contributing

New lessons, better analogies, clearer explanations and bug fixes are all welcome — see Adding a lesson. The one rule: if the animation teaches it, a test must assert it.


Built for the person who was told they're bad at algorithms.

About

Learn data structures & algorithms by watching them run. 44 interactive lessons — arrays to A*, Dijkstra and DP — with step-by-step animations, code synced in 4 languages, and 106 LeetCode problems. Free, no account.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages