├── .eslintrc.json ├── src ├── app │ ├── favicon.ico │ ├── layout.tsx │ ├── globals.css │ └── page.tsx ├── lib │ ├── types.ts │ └── utils.ts ├── algorithms │ ├── bubbleSort.ts │ ├── selectionSort.ts │ ├── insertionSort.ts │ ├── quickSort.ts │ └── mergeSort.ts ├── components │ └── Input │ │ ├── Slider.tsx │ │ └── Select.tsx └── context │ └── Visualizer.tsx ├── next.config.mjs ├── postcss.config.js ├── README.md ├── .gitignore ├── public ├── vercel.svg └── next.svg ├── tsconfig.json ├── package.json ├── LICENSE ├── tailwind.config.ts └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techprep-gh/sorting-visualizer/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sorting Visualizer 2 | 3 | - Bubble Sort 4 | - Selection Sort 5 | - Quick Sort 6 | - Insertion Sort 7 | - Merge Sort 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/lib/types.ts: -------------------------------------------------------------------------------- 1 | export type SortingAlgorithmType = 2 | | "bubble" 3 | | "insertion" 4 | | "selection" 5 | | "merge" 6 | | "quick"; 7 | 8 | export type AlgorithmInfo = { 9 | title: string; 10 | description: string; 11 | worstCase: string; 12 | averageCase: string; 13 | bestCase: string; 14 | }; 15 | 16 | export type SortingAlgorithmsData = { 17 | [key in SortingAlgorithmType]: AlgorithmInfo; 18 | }; 19 | 20 | export type AnimateSpeedType = "slow" | "medium" | "fast" | "lighning"; 21 | 22 | export type SelectOptionsType = { 23 | label: string; 24 | value: string; 25 | }; 26 | 27 | export type AnimationArrayType = [number[], boolean][]; 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sorting-visualizer", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "next": "14.1.0", 13 | "react": "^18", 14 | "react-dom": "^18", 15 | "react-icons": "^5.0.1" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "^20", 19 | "@types/react": "^18", 20 | "@types/react-dom": "^18", 21 | "autoprefixer": "^10.0.1", 22 | "eslint": "^8", 23 | "eslint-config-next": "14.1.0", 24 | "postcss": "^8", 25 | "tailwindcss": "^3.3.0", 26 | "typescript": "^5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Inter } from "next/font/google"; 3 | import "./globals.css"; 4 | import { SortingAlgorithmProvider } from "@/context/Visualizer"; 5 | 6 | const inter = Inter({ subsets: ["latin"] }); 7 | 8 | export const metadata: Metadata = { 9 | title: "Sorting Visualizer", 10 | description: "Visualize a selection of different sorting algorithms", 11 | }; 12 | 13 | export default function RootLayout({ 14 | children, 15 | }: Readonly<{ 16 | children: React.ReactNode; 17 | }>) { 18 | return ( 19 | 20 | 21 | {children} 22 | 23 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /src/algorithms/bubbleSort.ts: -------------------------------------------------------------------------------- 1 | import { AnimationArrayType } from "@/lib/types"; 2 | 3 | function runBubbleSort(array: number[], animations: AnimationArrayType) { 4 | for (let i = 0; i < array.length - 1; i++) { 5 | for (let j = 0; j < array.length - i - 1; j++) { 6 | animations.push([[j, j + 1], false]); 7 | if (array[j] > array[j + 1]) { 8 | animations.push([[j, array[j + 1]], true]); 9 | animations.push([[j + 1, array[j]], true]); 10 | [[array[j], array[j + 1]]] = [[array[j + 1], array[j]]]; 11 | } 12 | } 13 | } 14 | } 15 | 16 | export function generateBubbleSortAnimationArray( 17 | isSorting: boolean, 18 | array: number[], 19 | runAnimation: (animations: AnimationArrayType) => void 20 | ) { 21 | if (isSorting) return; 22 | if (array.length <= 1) return []; 23 | 24 | const animations: AnimationArrayType = []; 25 | const auxiliaryArray = array.slice(); 26 | runBubbleSort(auxiliaryArray, animations); 27 | runAnimation(animations); 28 | } 29 | -------------------------------------------------------------------------------- /src/components/Input/Slider.tsx: -------------------------------------------------------------------------------- 1 | import { MAX_ANIMATION_SPEED, MNI_ANIMATION_SPEED } from "@/lib/utils"; 2 | 3 | export const Slider = ({ 4 | min = MNI_ANIMATION_SPEED, 5 | max = MAX_ANIMATION_SPEED, 6 | step = 10, 7 | value, 8 | handleChange, 9 | isDisabled = false, 10 | }: { 11 | min?: number; 12 | max?: number; 13 | step?: number; 14 | value: number; 15 | handleChange: (e: React.ChangeEvent) => void; 16 | isDisabled?: boolean; 17 | }) => { 18 | return ( 19 |
20 | Slow 21 | handleChange(e)} 29 | className="w-full h-2 rounded-lg appearance-none cursor-pointer bg-gray-700" 30 | /> 31 | Fast 32 |
33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /src/algorithms/selectionSort.ts: -------------------------------------------------------------------------------- 1 | import { AnimationArrayType } from "@/lib/types"; 2 | 3 | function runSelectionSort(array: number[], animations: AnimationArrayType) { 4 | for (let i = 0; i < array.length - 1; i++) { 5 | let minIndex = i; 6 | for (let j = i + 1; j < array.length; j++) { 7 | animations.push([[j, i], false]); 8 | if (array[j] < array[minIndex]) { 9 | minIndex = j; 10 | } 11 | } 12 | animations.push([[i, array[minIndex]], true]); 13 | animations.push([[minIndex, array[i]], true]); 14 | [array[i], array[minIndex]] = [array[minIndex], array[i]]; 15 | } 16 | } 17 | 18 | export function generateSelectionSortAnimationArray( 19 | isSorting: boolean, 20 | array: number[], 21 | runAnimation: (animations: AnimationArrayType) => void 22 | ) { 23 | if (isSorting) return; 24 | if (array.length <= 1) return; 25 | 26 | const animations: AnimationArrayType = []; 27 | const auxiliaryArray = array.slice(); 28 | runSelectionSort(auxiliaryArray, animations); 29 | runAnimation(animations); 30 | } 31 | -------------------------------------------------------------------------------- /src/algorithms/insertionSort.ts: -------------------------------------------------------------------------------- 1 | import { AnimationArrayType } from "@/lib/types"; 2 | 3 | function runInsertionSort(array: number[], animations: AnimationArrayType) { 4 | for (let i = 1; i < array.length; i++) { 5 | animations.push([[i], false]); 6 | const currentValue = array[i]; 7 | let j = i - 1; 8 | while (j >= 0 && array[j] > currentValue) { 9 | animations.push([[j, j + 1, i], false]); 10 | array[j + 1] = array[j]; 11 | animations.push([[j + 1, array[j]], true]); 12 | j -= 1; 13 | } 14 | array[j + 1] = currentValue; 15 | animations.push([[j + 1, currentValue], true]); 16 | } 17 | } 18 | 19 | export function generateInsertionSortAnimationArray( 20 | isSorting: boolean, 21 | array: number[], 22 | runAnimation: (animations: AnimationArrayType) => void 23 | ) { 24 | if (isSorting) return; 25 | if (array.length <= 1) return []; 26 | const animations: AnimationArrayType = []; 27 | 28 | const auxiliaryArray = array.slice(); 29 | runInsertionSort(auxiliaryArray, animations); 30 | runAnimation(animations); 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 TechPrep 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | overflow: hidden; 28 | } 29 | 30 | @layer utilities { 31 | .text-balance { 32 | text-wrap: balance; 33 | } 34 | } 35 | 36 | .default-line-color { 37 | background: theme("colors.system.purple50"); 38 | } 39 | 40 | .change-line-color { 41 | background: theme("colors.system.green60"); 42 | } 43 | 44 | @keyframes pulse { 45 | 0%, 46 | 100% { 47 | opacity: 1; 48 | } 49 | 50% { 50 | opacity: 0.5; 51 | } 52 | } 53 | 54 | .pulse-animation { 55 | animation: pulse 1s cubic-bezier(0.4, 0, 0.6, 1) infinite; 56 | } 57 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Input/Select.tsx: -------------------------------------------------------------------------------- 1 | import { SelectOptionsType } from "@/lib/types"; 2 | import React from "react"; 3 | 4 | export const Select = ({ 5 | options, 6 | defaultValue, 7 | onChange, 8 | isDisabled = false, 9 | }: { 10 | options: SelectOptionsType[]; 11 | defaultValue: string; 12 | onChange: (e: React.ChangeEvent) => void; 13 | isDisabled?: boolean; 14 | }) => { 15 | return ( 16 |
17 | 29 |
30 | 35 | 36 | 37 |
38 |
39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | const config: Config = { 4 | content: [ 5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 8 | ], 9 | theme: { 10 | extend: { 11 | backgroundImage: { 12 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", 13 | "gradient-conic": 14 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", 15 | }, 16 | colors: { 17 | system: { 18 | purple10: "#240643", 19 | purple15: "#300b60", 20 | purple20: "#401075", 21 | purple30: "#5a1ba9", 22 | purple40: "#7526e3", 23 | purple50: "#9050e9", 24 | purple60: "#ad7bee", 25 | purple65: "#b78def", 26 | purple70: "#c29ef1", 27 | purple80: "#d7bff2", 28 | purple90: "#ece1f9", 29 | purple95: "#f6f2fb", 30 | 31 | green10: "#071b12", 32 | green15: "#0c2912", 33 | green20: "#1c3326", 34 | green30: "#194e31", 35 | green40: "#396547", 36 | green50: "#2e844a", 37 | green60: "#3ba755", 38 | green65: "#41b658", 39 | green70: "#45c65a", 40 | green80: "#91db8b", 41 | green90: "#cdefc4", 42 | green95: "#ebf7e6", 43 | green100: "#202b23", 44 | }, 45 | }, 46 | }, 47 | }, 48 | plugins: [], 49 | }; 50 | export default config; 51 | -------------------------------------------------------------------------------- /src/algorithms/quickSort.ts: -------------------------------------------------------------------------------- 1 | import { AnimationArrayType } from "@/lib/types"; 2 | 3 | function partition( 4 | array: number[], 5 | begin: number, 6 | finish: number, 7 | animations: AnimationArrayType 8 | ) { 9 | let i = begin; 10 | let j = finish + 1; 11 | const condition = true; 12 | const pivot = array[begin]; 13 | while (condition) { 14 | while (array[++i] <= pivot) { 15 | if (i === finish) break; 16 | animations.push([[i], false]); 17 | } 18 | while (array[--j] >= pivot) { 19 | if (j === begin) break; 20 | animations.push([[j], false]); 21 | } 22 | if (j <= i) break; 23 | animations.push([[i, array[j]], true]); 24 | animations.push([[j, array[i]], true]); 25 | [array[i], array[j]] = [array[j], array[i]]; 26 | } 27 | animations.push([[begin, array[j]], true]); 28 | animations.push([[j, array[begin]], true]); 29 | [array[begin], array[j]] = [array[j], array[begin]]; 30 | return j; 31 | } 32 | 33 | function runQuickort( 34 | array: number[], 35 | begin: number, 36 | finish: number, 37 | animations: AnimationArrayType 38 | ) { 39 | if (begin < finish) { 40 | const part = partition(array, begin, finish, animations); 41 | runQuickort(array, begin, part - 1, animations); 42 | runQuickort(array, part + 1, finish, animations); 43 | } 44 | } 45 | 46 | export function generateQuickSortAnimationArray( 47 | isSorting: boolean, 48 | array: number[], 49 | runAnimation: (animations: AnimationArrayType) => void 50 | ) { 51 | if (isSorting) return; 52 | if (array.length <= 1) return array; 53 | 54 | const animations: AnimationArrayType = []; 55 | const auxiliaryArray = array.slice(); 56 | runQuickort(auxiliaryArray, 0, array.length - 1, animations); 57 | runAnimation(animations); 58 | } 59 | -------------------------------------------------------------------------------- /src/algorithms/mergeSort.ts: -------------------------------------------------------------------------------- 1 | import { AnimationArrayType } from "@/lib/types"; 2 | 3 | function merge( 4 | array: number[], 5 | begin: number, 6 | middle: number, 7 | finish: number, 8 | animations: AnimationArrayType 9 | ) { 10 | const left = array.slice(begin, middle); 11 | const right = array.slice(middle, finish); 12 | 13 | let i = 0; 14 | let j = 0; 15 | let k = begin; 16 | while (i < left.length && j < right.length) { 17 | animations.push([[begin + i, middle + j], false]); 18 | if (left[i] <= right[j]) { 19 | animations.push([[k, left[i]], true]); 20 | array[k] = left[i]; 21 | i += 1; 22 | } else { 23 | animations.push([[k, right[j]], true]); 24 | array[k] = right[j]; 25 | j += 1; 26 | } 27 | k++; 28 | } 29 | while (i < left.length) { 30 | animations.push([[begin + i], false]); 31 | animations.push([[k, left[i]], true]); 32 | array[k] = left[i]; 33 | i += 1; 34 | k += 1; 35 | } 36 | while (j < right.length) { 37 | animations.push([[middle + j], false]); 38 | animations.push([[k, right[j]], true]); 39 | array[k] = right[j]; 40 | j += 1; 41 | k += 1; 42 | } 43 | } 44 | 45 | function runMergeSort(array: number[]) { 46 | const animations: AnimationArrayType = []; 47 | for (let k = 1; k < array.length; k = 2 * k) { 48 | for (let i = 0; i < array.length; i += 2 * k) { 49 | const begin = i; 50 | const middle = i + k; 51 | const finish = Math.min(i + 2 * k, array.length); 52 | merge(array, begin, middle, finish, animations); 53 | } 54 | } 55 | return animations; 56 | } 57 | 58 | export function generateMergeSortAnimationArray( 59 | isSorting: boolean, 60 | array: number[], 61 | runAnimation: (animations: AnimationArrayType) => void 62 | ) { 63 | if (isSorting) return; 64 | if (array.length <= 1) return []; 65 | 66 | const auxiliaryArray = array.slice(); 67 | const animations = runMergeSort(auxiliaryArray); 68 | runAnimation(animations); 69 | } 70 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { generateBubbleSortAnimationArray } from "@/algorithms/bubbleSort"; 2 | import { generateInsertionSortAnimationArray } from "@/algorithms/insertionSort"; 3 | import { generateMergeSortAnimationArray } from "@/algorithms/mergeSort"; 4 | import { generateQuickSortAnimationArray } from "@/algorithms/quickSort"; 5 | import { generateSelectionSortAnimationArray } from "@/algorithms/selectionSort"; 6 | import { SortingAlgorithmType } from "./types"; 7 | 8 | export function generateRandomNumberFromInterval(min: number, max: number) { 9 | return Math.floor(Math.random() * (max - min + 1) + min); 10 | } 11 | 12 | export const MNI_ANIMATION_SPEED = 100; 13 | export const MAX_ANIMATION_SPEED = 400; 14 | 15 | export const algorithmOptions = [ 16 | { label: "Bubble", value: "bubble" }, 17 | { label: "Quick", value: "quick" }, 18 | { label: "Merge", value: "merge" }, 19 | { label: "Insertion", value: "insertion" }, 20 | { label: "Selection", value: "selection" }, 21 | ]; 22 | 23 | export function generateAnimationArray( 24 | selectedAlgorithm: SortingAlgorithmType, 25 | isSorting: boolean, 26 | array: number[], 27 | runAnimation: (animations: [number[], boolean][]) => void 28 | ) { 29 | switch (selectedAlgorithm) { 30 | case "bubble": 31 | generateBubbleSortAnimationArray(isSorting, array, runAnimation); 32 | break; 33 | case "quick": 34 | generateQuickSortAnimationArray(isSorting, array, runAnimation); 35 | break; 36 | case "merge": 37 | generateMergeSortAnimationArray(isSorting, array, runAnimation); 38 | break; 39 | case "insertion": 40 | generateInsertionSortAnimationArray(isSorting, array, runAnimation); 41 | break; 42 | case "selection": 43 | generateSelectionSortAnimationArray(isSorting, array, runAnimation); 44 | break; 45 | default: 46 | break; 47 | } 48 | } 49 | 50 | export const sortingAlgorithmsData = { 51 | bubble: { 52 | title: "Bubble Sort", 53 | description: 54 | "A simple comparison-based sorting algorithm. Bubble sort repeatedly compares and swaps adjacent elements if they are in the wrong order, moving larger elements towards the end with each pass through the list. This process continues until the list is sorted and no more swaps are needed.", 55 | worstCase: "O(n²)", 56 | averageCase: "O(n²)", 57 | bestCase: "O(n)", 58 | }, 59 | insertion: { 60 | title: "Insertion Sort", 61 | description: 62 | "Insertion sort builds the final sorted array one element at a time, by repeatedly taking the next unsorted element and inserting it into its correct position among the previously sorted elements. This process continues until all elements have been inserted into their proper place, resulting in a sorted list.", 63 | worstCase: "O(n²)", 64 | averageCase: "O(n²)", 65 | bestCase: "O(n)", 66 | }, 67 | selection: { 68 | title: "Selection Sort", 69 | description: 70 | "Selection sort works by repeatedly finding the minimum element from the unsorted portion of the list and swapping it with the element at the current position. This process is continued for each position in the list, moving the boundary of the sorted and unsorted portions one element forward each time until the entire list is sorted.", 71 | worstCase: "O(n²)", 72 | averageCase: "O(n²)", 73 | bestCase: "O(n²)", 74 | }, 75 | merge: { 76 | title: "Merge Sort", 77 | description: 78 | "Merge sort divides the unsorted list into n sublists, each containing one element (a list of one element is considered sorted), and then repeatedly merges these sublists to produce new sorted sublists until there is only one sublist remaining, which is the sorted list. This algorithm uses a divide-and-conquer approach, splitting the list in half recursively and merging the sorted halves back together.", 79 | worstCase: "O(n log n)", 80 | averageCase: "O(n log n)", 81 | bestCase: "O(n log n)", 82 | }, 83 | quick: { 84 | title: "Quick Sort", 85 | description: 86 | "Quick sort selects a 'pivot' element from the array and partitions the other elements into two sub-arrays, according to whether they are less than or greater than the pivot. The sub-arrays are then sorted recursively, and the sorted sub-arrays are combined with the pivot to form the sorted array.", 87 | worstCase: "O(n²)", 88 | averageCase: "O(n log n)", 89 | bestCase: "O(n log n)", 90 | }, 91 | }; 92 | -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { Select } from "@/components/Input/Select"; 4 | import { Slider } from "@/components/Input/Slider"; 5 | import { useSortingAlgorithmContext } from "@/context/Visualizer"; 6 | import { SortingAlgorithmType } from "@/lib/types"; 7 | import { 8 | algorithmOptions, 9 | generateAnimationArray, 10 | sortingAlgorithmsData, 11 | } from "@/lib/utils"; 12 | import { FaPlayCircle } from "react-icons/fa"; 13 | import { RxReset } from "react-icons/rx"; 14 | 15 | export default function Home() { 16 | const { 17 | arrayToSort, 18 | isSorting, 19 | setAnimationSpeed, 20 | animationSpeed, 21 | selectedAlgorithm, 22 | setSelectedAlgorithm, 23 | requiresReset, 24 | resetArrayAndAnimation, 25 | runAnimation, 26 | } = useSortingAlgorithmContext(); 27 | 28 | const handleSelectChange = (e: React.ChangeEvent) => { 29 | setSelectedAlgorithm(e.target.value as SortingAlgorithmType); 30 | }; 31 | 32 | const handlePlay = () => { 33 | if (requiresReset) { 34 | resetArrayAndAnimation(); 35 | return; 36 | } 37 | 38 | generateAnimationArray( 39 | selectedAlgorithm, 40 | isSorting, 41 | arrayToSort, 42 | runAnimation 43 | ); 44 | }; 45 | 46 | return ( 47 |
48 |
49 |
53 |
54 |

55 | Sorting Visulizer 56 |

57 |
58 | setAnimationSpeed(Number(e.target.value))} 62 | /> 63 |