Playground Component

Cocktail Sort
Visualizer

An interactive Cocktail Sort visualization built with HTML, CSS, and JavaScript. Watch the algorithm sort the array by moving in both forward and backward directions, complete with adjustable animation speed.

Cocktail Sort Visualizer

CockTail 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> 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>CockTail Shaker Sort  Visualizer</h1>

<div class="controls">
    <button onclick="randomize()">Randomize</button>
    <button onclick="cocktailSort()">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 cocktailSort() {
    if (sorting) return;
    sorting = true;

    const bars = document.getElementsByClassName("bar");
    const n = values.length;

    let start = 0;
    let end = n - 1;
    let swapped = true;

    while (swapped) {

        swapped = false;

        // Left -> Right
        for (let i = start; i < end; i++) {

            bars[i].style.background = "#9c27b0";
            bars[i + 1].style.background = "#ff3b30";
            await sleep(speed);

            if (values[i] > values[i + 1]) {

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

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

                bars[i].style.background = "#ff9800";
                bars[i + 1].style.background = "#ff9800";

                swapped = true;
                await sleep(speed);
            }

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

        if (!swapped) break;

        swapped = false;
        end--;

        // Right -> Left
        for (let i = end; i > start; i--) {

            bars[i].style.background = "#9c27b0";
            bars[i - 1].style.background = "#ff3b30";
            await sleep(speed);

            if (values[i - 1] > values[i]) {

                [values[i - 1], values[i]] = [values[i], values[i - 1]];

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

                bars[i - 1].style.background = "#ff9800";
                bars[i].style.background = "#ff9800";

                swapped = true;
                await sleep(speed);
            }

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

        start++;
    }

    for (let i = 0; i < n; i++) {
        bars[i].style.background = "#39d353";
        await sleep(5);
    }

    sorting = false;
}

randomize();

</script>

</body>
</html>

  

About this Component

Cocktail Sort, also known as Cocktail Shaker Sort or Bidirectional Bubble Sort, is a variation of Bubble Sort that traverses the array in both directions during each pass. Instead of only pushing the largest elements toward the end, it also moves the smallest elements toward the beginning, reducing the number of passes required for partially sorted arrays. This interactive visualization lets you observe the forward and backward passes, watch comparisons and swaps happen in real time, and control the animation speed to better understand how the algorithm works. Cocktail Sort has an average and worst-case time complexity of O(n²), while its best-case complexity is O(n) when the array is already sorted. It is an in-place and stable sorting algorithm, requiring only O(1) extra memory.

Explore More Components

Discover more components from the Playground.