Playground Component

Quick Sort
Visualizer

An interactive Quick Sort visualization built with HTML, CSS, and JavaScript. Watch how the algorithm selects a pivot, partitions the array, and recursively sorts elements with adjustable animation speed.

Quick Sort Visualizer

Quick Sort Visualizer

Copy Code


  
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quick Sort Visualizer</title>

<!-- <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet"> -->

<style>
*{
    margin:0;
    padding:0;
    box-sizing:border-box;
}

:root{
    --bg:#090909;
    --panel:#111111;
    --panel2:#171717;
    --gold:#f4c430;
    --gold2:#ffd54d;
    --border:#3a2d08;
    --text:#f5f5f5;
}

body{
    font-family:'Poppins',sans-serif;
    background:
        radial-gradient(circle at top,#1b1606 0%,#090909 35%),
        var(--bg);
    color:var(--text);
    min-height:100vh;
    display:flex;
    flex-direction:column;
    align-items:center;
    padding:40px 25px;
}

h1{
    font-size:3rem;
    font-weight:700;
    color:var(--gold);
    margin-bottom:30px;
    text-shadow:0 0 18px rgba(244,196,48,.18);
    letter-spacing:.5px;
}

.controls{
    display:flex;
    gap:18px;
    flex-wrap:wrap;
    justify-content:center;
    margin-bottom:35px;
}

button{
    min-width:170px;
    padding:15px 22px;
    font-size:17px;
    font-weight:600;
    border-radius:14px;
    border:1px solid #705510;
    background:linear-gradient(180deg,#ffd54d,#e7b817);
    color:#121212;
    cursor:pointer;
    transition:.28s;
    box-shadow:
        0 8px 20px rgba(0,0,0,.45),
        inset 0 1px 0 rgba(255,255,255,.35);
}

button:hover{
    transform:translateY(-3px);
    box-shadow:
        0 14px 30px rgba(244,196,48,.22),
        inset 0 1px 0 rgba(255,255,255,.4);
}

button:active{
    transform:scale(.98);
}

#container{
    width:min(94%,1300px);
    height:590px;
    background:linear-gradient(180deg,#121212,#0b0b0b);
    border:1px solid var(--border);
    border-radius:24px;
    display:flex;
    align-items:flex-end;
    justify-content:center;
    gap:4px;
    padding:16px;
    box-shadow:
        0 20px 45px rgba(0,0,0,.55),
        inset 0 0 0 1px rgba(255,255,255,.03),
        0 0 35px rgba(244,196,48,.06);
    position:relative;
    overflow:hidden;
}

#container::before{
    content:"";
    position:absolute;
    inset:0;
    pointer-events:none;
    background:
        linear-gradient(rgba(255,255,255,.03) 1px,transparent 1px);
    background-size:100% 60px;
    opacity:.35;
}

.bar{
    width:12px;
    background:linear-gradient(to top,#b88700,#ffd54d);
    border-radius:4px 4px 0 0;
    transition:
        height linear,
        background .2s linear,
        transform .15s linear;
    box-shadow:0 0 10px rgba(244,196,48,.15);
    z-index:1;
}

@media(max-width:900px){
    h1{
        font-size:2.2rem;
    }

    button{
        min-width:145px;
        font-size:15px;
    }

    #container{
        height:470px;
    }

    .bar{
        width:8px;
        gap:2px;
    }
}
</style>
</head>

<body>

<h1>Quick Sort Visualizer</h1>

<div class="controls">
    <button onclick="randomize()">Randomize</button>
    <button onclick="quickSort()">Sort</button>
    <button id="speedBtn" onclick="toggleSpeed()">Speed: Normal</button>
</div>

<div id="container"></div>

<script>

let sorting = false;

const speedLevels = [
    { name: "Very Slow", delay: 500 },
    { name: "Slow", delay: 120 },
    { name: "Normal", delay: 70 },
    { name: "Fast", delay: 35 },
    { name: "Very Fast", delay: 1 }
];

let speedIndex = 2;
let speed = speedLevels[speedIndex].delay;

const container = document.getElementById("container");

let values=[];

function toggleSpeed() {
    speedIndex++;
    if (speedIndex >= speedLevels.length) speedIndex = 0;
    speed = speedLevels[speedIndex].delay;
    document.getElementById("speedBtn").textContent =
        "Speed: " + speedLevels[speedIndex].name;
}

function createBars(){
    container.innerHTML="";
    values.forEach(v=>{
        const bar=document.createElement("div");
        bar.className="bar";
        bar.style.height=v+"px";
        container.appendChild(bar);
    });
}

function randomize(){
    values=[];
    for(let i=0;i<100;i++){
        values.push(Math.floor(Math.random()*350)+30);
    }
    createBars();
}

function sleep(ms){
    return new Promise(resolve=>setTimeout(resolve,ms));
}

async function quickSort() {
    if (sorting) return;
    sorting = true;

    const bars = document.getElementsByClassName("bar");

    await quickSortHelper(0, values.length - 1, bars);

    for (let i = 0; i < values.length; i++) {
        bars[i].style.background = "#39d353";
    }

    sorting = false;
}

async function quickSortHelper(low, high, bars) {
    if (low < high) {
        const pi = await partition(low, high, bars);

        bars[pi].style.background = "#39d353";

        await quickSortHelper(low, pi - 1, bars);
        await quickSortHelper(pi + 1, high, bars);
    } else if (low === high) {
        bars[low].style.background = "#39d353";
    }
}

async function partition(low, high, bars) {

    const pivot = values[high];

    bars[high].style.background = "#9c27b0"; // Pivot

    let i = low - 1;

    for (let j = low; j < high; j++) {

        bars[j].style.background = "#ff3b30"; // Comparing
        await sleep(speed);

        if (values[j] < pivot) {

            i++;

            [values[i], values[j]] = [values[j], values[i]];

            bars[i].style.height = values[i] + "px";
            bars[j].style.height = values[j] + "px";

            bars[i].style.background = "#ff9800"; // Swapped
            await sleep(speed);
        }

        if (i !== j) {
            bars[j].style.background = "linear-gradient(to top,#b88700,#ffd54d)";
        }
    }

    [values[i + 1], values[high]] = [values[high], values[i + 1]];

    bars[i + 1].style.height = values[i + 1] + "px";
    bars[high].style.height = values[high] + "px";

    await sleep(speed);

    bars[high].style.background = "linear-gradient(to top,#b88700,#ffd54d)";

    return i + 1;
}

randomize();

</script>

</body>
</html>

About this Component

Quick Sort is one of the fastest and most widely used comparison-based sorting algorithms. It works by selecting a pivot element, partitioning the array so that smaller elements move to the left and larger elements move to the right, and then recursively sorting the resulting subarrays. This interactive visualization allows you to observe how the pivot is selected, how elements are partitioned, and how recursive calls gradually sort the entire array. You can randomize the array, adjust the animation speed, and watch each step of the algorithm unfold in real time. Quick Sort has an average-case time complexity of O(n log n), making it one of the most efficient general-purpose sorting algorithms. Although its worst-case complexity is O(n²), good pivot selection strategies make that scenario uncommon in practice.

Explore More Components

Discover more components from the Playground.