An interactive algorithms visualizer built with Vite + React + TypeScript. Features sorting, pathfinding, graph algorithms, and dynamic programming visualizations with an extensible architecture for adding more algorithms.
- Bubble Sort - Classic O(n²) comparison-based algorithm
- Merge Sort - Efficient O(n log n) divide-and-conquer algorithm
- Quick Sort - Fast O(n log n) pivot-based algorithm with partition animation
- Interactive Controls:
▶️ Play - Run the algorithm automatically- ⏸️ Pause - Stop the animation
- ⏭️ Step - Execute one step at a time
- ↻ Reset - Start over
- Speed Control - Adjust animation speed (10ms - 500ms)
- Real-time Metrics:
- Comparisons count
- Swaps count
- Current status
- Visual Feedback:
- Yellow bars = currently comparing
- Red bars = swapping
- Green bars = sorted
- Orange bars = pivot (Quick Sort)
- BFS (Breadth-First Search) - Finds shortest path in unweighted graphs
- Interactive Grid Editor:
- 🧱 Draw walls
- 🧹 Erase walls
- 🚀 Move start position
- 🎯 Move end position
- Preloaded Maze - Start with an interesting pattern
- Real-time Metrics:
- Cells visited
- Path length
- Search status
- Visual Feedback:
- Orange = currently exploring
- Blue = visited cells
- Purple = final path
- DFS Traversal - Depth-first search on directed graphs
- Topological Sort - Linear ordering of vertices in a DAG
- Strongly Connected Components (SCC) - Kosaraju's algorithm
- Cycle Detection - Three approaches:
- DFS 3-Color method
- Kahn's algorithm (BFS-based topological sort)
- SCC-based detection
- Interactive Graph Editor:
- ➕ Add/remove nodes and edges
- 🖱️ Drag nodes
- 🎯 Select starting node for DFS
- Graph Presets: Random, Chain, Complete, Tree
- Visual Feedback:
- Yellow = visiting
- Green = visited
- Red = cycle edges
- 0/1 Knapsack - Maximize value with weight constraints
- Coin Change - Minimum coins to make amount (unlimited coins)
- Interactive Parameter Input:
- Weights and values for Knapsack
- Coins and amount for Coin Change
- DP Table Visualization:
- 2D table for Knapsack (items × capacity)
- 1D array for Coin Change (amounts)
- Orange highlight = current cell being computed
- Index Labels: Clear 0-based indexing for rows/columns
- Settings Saved: Algorithm selections, speeds, parameters persist across browser sessions
- Graph State: Current graph structure and settings saved locally
The project follows a clean, extensible architecture:
src/
├── algorithms/
│ ├── sorting/
│ │ ├── bubbleSort.ts # Bubble sort generator
│ │ ├── mergeSort.ts # Merge sort generator
│ │ ├── quickSort.ts # Quick sort generator
│ │ └── index.ts # Algorithm registry
│ ├── pathfinding/
│ │ ├── bfs.ts # BFS generator
│ │ └── index.ts # Algorithm registry
│ ├── graph/
│ │ ├── dfs.ts # DFS traversal
│ │ ├── topologicalSort.ts # Topological sort
│ │ ├── scc.ts # Strongly connected components
│ │ ├── cycleDetectionDFS.ts # Cycle detection (DFS)
│ │ ├── cycleDetectionKahn.ts # Cycle detection (Kahn's)
│ │ ├── cycleDetectionSCC.ts # Cycle detection (SCC)
│ │ └── index.ts # Algorithm registry
│ └── dp/
│ ├── knapsack.ts # 0/1 Knapsack
│ ├── coinChange.ts # Coin change
│ └── index.ts # Algorithm registry
├── components/
│ ├── ControlPanel.tsx # Playback controls
│ ├── SortingBar.tsx # Individual bar component
│ ├── SortingVisualizer.tsx # Sorting view
│ ├── GridCell.tsx # Grid cell component
│ ├── PathfindingVisualizer.tsx # Pathfinding view
│ ├── GraphVisualizer.tsx # Graph algorithms view
│ ├── DPVisualizer.tsx # DP algorithms view
│ └── Navigation.tsx # Top navigation
├── hooks/
│ ├── useSortingVisualization.ts # Sorting state management
│ ├── usePathfindingVisualization.ts # Pathfinding state management
│ ├── useGraphVisualization.ts # Graph state management
│ └── useDPVisualization.ts # DP state management
├── types/
│ └── index.ts # TypeScript type definitions
└── utils/
├── grid.ts # Grid utility functions
└── graph.ts # Graph utility functions
- Create a new file (e.g.,
selectionSort.ts):
import { SortingStep, SortingAlgorithm } from '../../types';
function* selectionSortGenerator(array: number[]): Generator<SortingStep, void, unknown> {
// Your implementation using yield for each step
}
export const selectionSort: SortingAlgorithm = {
name: 'Selection Sort',
key: 'selection',
generate: selectionSortGenerator,
};- Register in
algorithms/sorting/index.ts:
import { selectionSort } from './selectionSort';
export const sortingAlgorithms: Record<string, SortingAlgorithm> = {
bubble: bubbleSort,
merge: mergeSort,
quick: quickSort,
selection: selectionSort, // Add here
};- Create a new file (e.g.,
dijkstra.ts):
import { PathfindingStep, PathfindingAlgorithm, Cell, GridPosition } from '../../types';
function* dijkstraGenerator(
grid: Cell[][],
start: GridPosition,
end: GridPosition
): Generator<PathfindingStep, void, unknown> {
// Your implementation using yield for each step
}
export const dijkstra: PathfindingAlgorithm = {
name: 'Dijkstra\'s Algorithm',
key: 'dijkstra',
generate: dijkstraGenerator,
};- Register in
algorithms/pathfinding/index.ts:
import { dijkstra } from './dijkstra';
export const pathfindingAlgorithms: Record<string, PathfindingAlgorithm> = {
bfs: bfs,
dijkstra: dijkstra, // Add here
};- Create a new file (e.g.,
bellmanFord.ts):
import { GraphStep, GraphAlgorithm } from '../../types';
function* bellmanFordGenerator(nodes: GraphNode[], edges: GraphEdge[]): Generator<GraphStep, void, unknown> {
// Your implementation using yield for each step
}
export const bellmanFord: GraphAlgorithm = {
name: 'Bellman-Ford Algorithm',
key: 'bellmanFord',
generate: bellmanFordGenerator,
};- Register in
algorithms/graph/index.ts:
import { bellmanFord } from './bellmanFord';
export const graphAlgorithms: Record<string, GraphAlgorithm> = {
dfs: dfs,
topologicalSort: topologicalSort,
scc: scc,
cycleDetectionDFS: cycleDetectionDFS,
cycleDetectionKahn: cycleDetectionKahn,
cycleDetectionSCC: cycleDetectionSCC,
bellmanFord: bellmanFord, // Add here
};- Create a new file (e.g.,
longestCommonSubsequence.ts):
import { DPStep, DPAlgorithm } from '../../types';
function* lcsGenerator(str1: string, str2: string): Generator<DPStep, void, unknown> {
// Your implementation using yield for each step
}
export const lcs: DPAlgorithm = {
name: 'Longest Common Subsequence',
key: 'lcs',
generate: lcsGenerator,
};- Register in
algorithms/dp/index.ts:
import { lcs } from './longestCommonSubsequence';
export const dpAlgorithms: Record<string, DPAlgorithm> = {
knapsack: knapsack,
coinChange: coinChange,
lcs: lcs, // Add here
};- Node.js 18+
- npm or yarn
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run previewThe app will be available at http://localhost:3000
Ready to add:
- Dijkstra's Algorithm - Weighted shortest path
- A Search* - Heuristic-based pathfinding
- Heap Sort - Heap-based sorting
- Selection Sort - Simple comparison sort
- Insertion Sort - Efficient for small arrays
- DFS (Depth-First Search) - Alternative pathfinding
- Bi-directional Search - Search from both ends
- Maze Generation - Random maze algorithms
- Bellman-Ford - Shortest paths with negative weights
- Floyd-Warshall - All-pairs shortest paths
- Longest Common Subsequence - String DP problem
- Matrix Chain Multiplication - Optimal parenthesization
- Edit Distance - String similarity DP
- Vite - Fast build tool and dev server
- React 18 - UI library with hooks
- TypeScript - Type safety
- CSS Variables - Theming support
- Generator Functions - Step-by-step algorithm execution
- LocalStorage - Settings persistence across sessions
ISC License