Skip to content

Commit 2b46604

Browse files
Merge pull request #9 from tusharpatel0504/feature/Selection-Sort-Visualizer
implement insertion sort visualizer
2 parents 2341d51 + 1f1b3a1 commit 2b46604

File tree

4 files changed

+160
-0
lines changed

4 files changed

+160
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// src/algorithms/sorting/InsertionSort.js
2+
export function* insertionSort(array) {
3+
const arr = [...array];
4+
const n = arr.length;
5+
6+
for (let i = 1; i < n; i++) {
7+
// mark the current index being considered (matches selectionSort behavior)
8+
yield { type: "compare", indices: [i] };
9+
10+
// perform insertion by swapping adjacent elements until correct position
11+
let j = i;
12+
while (j > 0) {
13+
// compare the pair we're about to potentially swap
14+
yield { type: "compare", indices: [j - 1, j] };
15+
16+
if (arr[j - 1] > arr[j]) {
17+
// swap adjacent
18+
[arr[j - 1], arr[j]] = [arr[j], arr[j - 1]];
19+
yield { type: "swap", indices: [j - 1, j], array: [...arr] };
20+
j--;
21+
} else {
22+
break;
23+
}
24+
}
25+
26+
// if element moved, indicate insertion position (use "min" to match visual cue)
27+
if (j !== i) {
28+
yield { type: "min", index: j };
29+
}
30+
}
31+
32+
yield { type: "done", array: arr };
33+
}
34+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from "react";
2+
3+
const COLORS = {
4+
default: "bg-blue-500 shadow-[0_0_10px_#3b82f6]",
5+
comparing: "bg-yellow-400 shadow-[0_0_12px_#facc15]",
6+
min: "bg-green-500 shadow-[0_0_12px_#22c55e]",
7+
swap: "bg-red-500 shadow-[0_0_12px_#ef4444]",
8+
};
9+
10+
export default function InsertionSortVisualizer({ array, highlight }) {
11+
const maxValue = Math.max(...array, 1); // Avoid division by zero
12+
const containerHeight = 288; // px (matches h-72)
13+
14+
return (
15+
<div className="flex items-end justify-center space-x-2 h-72 mt-10 transition-all duration-500">
16+
{array.map((value, idx) => {
17+
let color = COLORS.default;
18+
if (highlight?.type === "compare" && highlight.indices?.includes(idx))
19+
color = COLORS.comparing;
20+
if (highlight?.type === "min" && highlight.index === idx)
21+
color = COLORS.min;
22+
if (highlight?.type === "swap" && highlight.indices?.includes(idx))
23+
color = COLORS.swap;
24+
25+
// Normalize height relative to the maximum value
26+
const height = Math.max((value / maxValue) * containerHeight, 15); // minimum 15px for visibility
27+
28+
return (
29+
<div
30+
key={idx}
31+
className={`${color} w-6 transition-all duration-300 rounded-t-md`}
32+
style={{ height: `${height}px` }}
33+
></div>
34+
);
35+
})}
36+
</div>
37+
);
38+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import React, { useState } from "react";
2+
import { Toaster } from "react-hot-toast";
3+
import InsertionSortVisualizer from "../../components/sorting/InsertionSortVisualizer";
4+
import { insertionSort } from "../../algorithms/sorting/InsertionSort";
5+
6+
export default function InsertionSort() {
7+
const [array, setArray] = useState([]);
8+
const [input, setInput] = useState("");
9+
const [highlight, setHighlight] = useState(null);
10+
const [isRunning, setIsRunning] = useState(false);
11+
12+
const handleStart = async () => {
13+
if (isRunning || array.length === 0) return;
14+
setIsRunning(true);
15+
16+
const gen = insertionSort(array);
17+
for (let step of gen) {
18+
setHighlight(step);
19+
if (step.array) setArray([...step.array]);
20+
await new Promise((r) => setTimeout(r, 500));
21+
}
22+
23+
setHighlight({ type: "done" });
24+
setIsRunning(false);
25+
};
26+
27+
const handleReset = () => {
28+
setArray([]);
29+
setInput("");
30+
setHighlight(null);
31+
};
32+
33+
const handleInput = (e) => {
34+
setInput(e.target.value);
35+
const numbers = e.target.value
36+
.split(",")
37+
.map((n) => parseInt(n.trim()))
38+
.filter((n) => !isNaN(n));
39+
setArray(numbers);
40+
};
41+
42+
return (
43+
<div className="min-h-screen bg-black text-gray-200 flex flex-col items-center p-6">
44+
<Toaster position="top-center" />
45+
<h1 className="text-4xl font-extrabold mb-8 text-indigo-400 drop-shadow-lg">
46+
Insertion Sort Visualizer
47+
</h1>
48+
49+
<input
50+
type="text"
51+
value={input}
52+
onChange={handleInput}
53+
placeholder="Enter numbers separated by commas"
54+
className="border-2 border-indigo-500 bg-gray-900 text-indigo-200 rounded-lg p-3 w-96 text-center shadow-lg focus:ring-2 focus:ring-indigo-400 outline-none"
55+
/>
56+
57+
<div className="space-x-4 mt-6">
58+
<button
59+
onClick={handleStart}
60+
disabled={isRunning}
61+
className={`${
62+
isRunning
63+
? "bg-indigo-700 text-gray-300 cursor-not-allowed"
64+
: "bg-indigo-600 hover:bg-indigo-500"
65+
} px-6 py-2 rounded-lg text-white font-semibold shadow-md transition-all duration-300`}
66+
>
67+
{isRunning ? "Sorting..." : "Start Visualization"}
68+
</button>
69+
<button
70+
onClick={handleReset}
71+
className="bg-gray-700 hover:bg-gray-600 px-6 py-2 rounded-lg text-white font-semibold shadow-md transition-all duration-300"
72+
>
73+
Reset
74+
</button>
75+
</div>
76+
77+
<div className="mt-15">
78+
<InsertionSortVisualizer array={array} highlight={highlight} />
79+
</div>
80+
81+
</div>
82+
);
83+
}
84+

src/pages/sorting/SortingPage.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// src/pages/SortingPage.jsx
22
import React, { useState } from "react";
33
import SelectionSort from "./SelectionSort";
4+
import InsertionSort from "./InsertionSort";
45

56
export default function SortingPage() {
67
const [selectedAlgo, setSelectedAlgo] = useState("");
@@ -9,6 +10,8 @@ export default function SortingPage() {
910
switch (selectedAlgo) {
1011
case "selection":
1112
return <SelectionSort />;
13+
case "insertion":
14+
return <InsertionSort />;
1215
// You can add more later like:
1316
// case "bubble": return <BubbleSort />;
1417
// case "merge": return <MergeSort />;
@@ -37,6 +40,7 @@ export default function SortingPage() {
3740
>
3841
<option value="">Select Algorithm</option>
3942
<option value="selection">Selection Sort</option>
43+
<option value="insertion">Insertion Sort</option>
4044
</select>
4145

4246
<button

0 commit comments

Comments
 (0)