Loading repository data…
Loading repository data…
salsadsid / repository
Interactive DSA visualizer - sorting algorithms with play/pause/scrub, synced pseudocode, and live variable tracking. Next.js + Tailwind, accessibility-first (prefers-reduced-motion).
Built with Next.js 16 and Tailwind CSS 4 to make DSA easier to see, touch, and learn.
/algorithms/sortingStep through Bubble, Selection, and Insertion sort:
Space and ←/→ shortcuts)i, j, min) under the bars and value chips (key, swapped)/data-structures/arraysPaste any JSON matrix, color each value, and see how grids map to rows and columns:
null all renderBoth tools ship with an inline learning panel (concept, use cases, complexity, and
C++ / Python / JavaScript / TypeScript code), light + dark themes, a responsive
layout, and full prefers-reduced-motion support.
A condensed version of the in-app learning panels — enough to understand what you're watching.
Sorting arranges items into order (here, smallest → largest). The three sorts in this app share three traits:
Two terms worth knowing:
Idea: repeatedly walk the list and swap any adjacent pair that's out of order, so large values "bubble" to the right.
How it works: on each pass, compare a[j] with a[j+1] and swap if needed. After
pass k, the largest k values are parked at the end. If a whole pass makes no
swaps, the array is already sorted and we stop early.
| Best | Average | Worst | Space | Stable |
|---|---|---|---|---|
| O(n) | O(n²) | O(n²) | O(1) | Yes |
Why learn it: the gentlest introduction to sorting, and the early-exit shows how an algorithm can detect "already sorted" cheaply (the O(n) best case).
Idea: each pass finds the smallest remaining value and drops it into the next slot.
How it works: scan the unsorted region for the index of its minimum, then swap that minimum into the front of the region. Repeat with a region that shrinks by one each time.
| Best | Average | Worst | Space | Stable |
|---|---|---|---|---|
| O(n²) | O(n²) | O(n²) | O(1) | No |
Why learn it: it always does the fewest swaps (at most n − 1), which matters when writing to memory is expensive — even though it never gets faster on sorted input.
Idea: grow a sorted prefix one element at a time, inserting each new value into its correct spot — exactly how most people sort a hand of playing cards.
How it works: take a[i] as the key, slide every larger value in the sorted
prefix one step right, then drop the key into the gap that opens up.
| Best | Average | Worst | Space | Stable |
|---|---|---|---|---|
| O(n) | O(n²) | O(n²) | O(1) | Yes |
Why learn it: the best real-world performer of the three on small or nearly-sorted
data, and it's used as the base case inside fast hybrid sorts like Timsort (Python, Java)
and introsort (C++ std::sort).
A 2D array is an array of arrays — a grid of rows × cols cells reached with two
indices, matrix[row][col]. Most languages store it in row-major order (all of row
0, then all of row 1, …), which is why iterating row-by-row is cache-friendly.
| Operation | Time |
|---|---|
| Access / update a cell | O(1) |
| Search for a value | O(r · c) |
| Iterate (row-major) | O(r · c) |
| Space | O(r · c) |
Used everywhere: game boards, images (a grid of pixels), adjacency matrices for graphs, and dynamic-programming tables.
O(1) constant · O(log n) halving each step · O(n) one pass · O(n log n) the best
general sorts · O(n²) nested passes (the sorts above). Lower is better as n grows.
Each algorithm is a generator that returns a flat list of step snapshots:
Step = {
array, // the working array at this moment
highlights, // which bars are comparing / swapping / sorted …
pointers, // index variables (i, j, min) drawn under the bars
vars, // scalar variables (key, swapped) shown as chips
line, // the active pseudocode line
message, // the narration text
stats, // cumulative { comparisons, swaps, writes }
}
A small usePlayer hook plays, pauses, steps, and scrubs through that list, and shared
components (BarChart, Pseudocode, PlayerControls, StatsRow, LearningTabs)
render it. New algorithms only need to emit steps — the player and UI come for free.
| Layer | Tools |
|---|---|
| Framework | Next.js 16 (App Router) · React 19 |
| Styling | Tailwind CSS 4 · CSS variables for theming |
| Fonts | Geist Sans + Geist Mono via next/font |
| Utilities | clsx, tailwind-merge |
| Linting | ESLint 9 (eslint-config-next) |
No backend, no database — it runs entirely in the browser.
src/
├── app/
│ ├── page.js # Landing page (live auto-sort hero demo)
│ ├── layout.js # Root layout, fonts, theme bootstrap
│ ├── globals.css # Design tokens + motion system
│ ├── roadmap/page.jsx # What's shipped / planned
│ ├── algorithms/
│ │ ├── page.jsx # Algorithms hub
│ │ └── sorting/page.jsx # Sorting Visualizer
│ └── data-structures/
│ └── arrays/page.jsx # 2D Array Visualizer
├── components/
│ ├── ThemeToggle.jsx # Light/dark toggle (floating button)
│ ├── algorithms/ # BarChart, PlayerControls, Pseudocode,
│ │ # usePlayer, StatsRow, VarChips, Confetti, HeroDemo …
│ ├── array/ # InputPanel, ArrayGrid, ColorSettings, LearningPanel
│ └── layout/ # PageShell, BackLink, Footer
└── lib/
├── algorithms/ # sorting.js (step model), presets, roles, snippets
└── array/ # parser, presets, snippets
See /roadmap in the app for the full list. Next up:
counting sort & frequency arrays, then merge/quick sort, binary search, and the
core array techniques (prefix sums, two pointers, sliding window).
MIT. Feel free to fork, learn from, or extend.
Built by Salman Sadik Siddiquee · Repository