Playground Component

Odd-Even Sort
Visualizer

An interactive Odd-Even Sort visualization built with HTML, CSS, and JavaScript. Watch the algorithm alternate between odd and even indexed comparisons until the array is fully sorted, complete with adjustable animation speed.

Odd-Even Sort Visualizer

Odd-Even 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>Odd-Even Sort Visualizer</h1>

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

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

    let sorted = false;

    while (!sorted) {

        sorted = true;

        // Odd phase
        for (let i = 1; i < n - 1; i += 2) {

            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";

                sorted = false;
                await sleep(speed);
            }

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

        // Even phase
        for (let i = 0; i < n - 1; i += 2) {

            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";

                sorted = false;
                await sleep(speed);
            }

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

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

    sorting = false;
}


randomize();

</script>

</body>
</html>

  

About this Component

Odd-Even Sort, also known as Brick Sort, is a variation of Bubble Sort designed to perform comparisons in alternating phases. During the odd phase, it compares adjacent elements at odd indices, while during the even phase, it compares adjacent elements at even indices. These two phases repeat until no swaps are required, indicating that the array is sorted. This interactive visualization lets you observe both odd and even passes, follow each comparison and swap in real time, randomize the input array, and adjust the animation speed to better understand how the algorithm progresses. Odd-Even Sort has a best-case time complexity of O(n) when the array is already sorted, while its average and worst-case time complexity is O(n²). It is an in-place and stable sorting algorithm that requires only O(1) additional memory.

Explore More Components

Discover more components from the Playground.