Playground Component
Cycle Sort
Visualizer
An interactive Cycle Sort visualization built with HTML, CSS, and JavaScript. Watch how the algorithm minimizes memory writes by placing each element directly into its correct position, complete with adjustable animation speed.

Cycle 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>Cycle Sort Visualizer</h1>
<div class="controls">
<button onclick="randomize()">Randomize</button>
<button onclick="cycleSort()">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 cycleSort() {
if (sorting) return;
sorting = true;
const bars = document.getElementsByClassName("bar");
const n = values.length;
for (let cycleStart = 0; cycleStart < n - 1; cycleStart++) {
let item = values[cycleStart];
let pos = cycleStart;
// Find where to put the item
for (let i = cycleStart + 1; i < n; i++) {
bars[i].style.background = "#9c27b0";
bars[cycleStart].style.background = "#ff3b30";
await sleep(speed);
if (values[i] < item) pos++;
bars[i].style.background =
"linear-gradient(to top,#b88700,#ffd54d)";
bars[cycleStart].style.background =
"linear-gradient(to top,#b88700,#ffd54d)";
}
if (pos === cycleStart) continue;
while (item === values[pos]) pos++;
// First write
if (pos !== cycleStart) {
bars[pos].style.background = "#ff9800";
bars[cycleStart].style.background = "#ff9800";
[item, values[pos]] = [values[pos], item];
bars[pos].style.height = values[pos] + "px";
await sleep(speed);
bars[pos].style.background =
"linear-gradient(to top,#b88700,#ffd54d)";
bars[cycleStart].style.background =
"linear-gradient(to top,#b88700,#ffd54d)";
}
// Rotate the cycle
while (pos !== cycleStart) {
pos = cycleStart;
for (let i = cycleStart + 1; i < n; i++) {
bars[i].style.background = "#9c27b0";
await sleep(speed);
if (values[i] < item) pos++;
bars[i].style.background =
"linear-gradient(to top,#b88700,#ffd54d)";
}
while (item === values[pos]) pos++;
bars[pos].style.background = "#ff9800";
[item, values[pos]] = [values[pos], item];
bars[pos].style.height = values[pos] + "px";
await sleep(speed);
bars[pos].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
Cycle Sort is a comparison-based sorting algorithm designed to minimize the number of writes to memory. Instead of repeatedly swapping adjacent elements, it determines the final position of each element and places it directly where it belongs. This makes Cycle Sort one of the algorithms with the minimum possible number of writes, making it useful in situations where memory writes are expensive. This interactive visualization lets you observe how each cycle is formed, watch elements jump directly to their final positions, randomize the input array, and control the animation speed to better understand the algorithm's unique behavior. Cycle Sort has a best-case time complexity of O(n²), and its average and worst-case time complexity is also O(n²). Although it performs many comparisons, it minimizes writes to just O(n). It is an in-place sorting algorithm requiring only O(1) additional memory, but it is not stable because equal elements may change their relative order.
Explore More Components
Discover more components from the Playground.



