Playground Component
Merge Sort
Visualizer
An interactive Merge Sort visualization built with HTML, CSS, and JavaScript. Watch the divide-and-conquer process split arrays into smaller parts before merging them back together in sorted order.

Merge 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>Merge 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>Merge Sort Visualizer</h1>
<div class="controls">
<button onclick="randomize()">Randomize</button>
<button onclick="mergeSort()">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 mergeSort() {
if (sorting) return;
sorting = true;
const bars = document.getElementsByClassName("bar");
await mergeSortHelper(0, values.length - 1, bars);
for (let i = 0; i < values.length; i++) {
bars[i].style.background = "#39d353";
}
sorting = false;
}
async function mergeSortHelper(left, right, bars) {
if (left >= right) return;
const mid = Math.floor((left + right) / 2);
await mergeSortHelper(left, mid, bars);
await mergeSortHelper(mid + 1, right, bars);
await merge(left, mid, right, bars);
}
async function merge(left, mid, right, bars) {
const leftArr = values.slice(left, mid + 1);
const rightArr = values.slice(mid + 1, right + 1);
let i = 0, j = 0, k = left;
while (i < leftArr.length && j < rightArr.length) {
bars[k].style.background = "#ff3b30";
await sleep(speed);
if (leftArr[i] <= rightArr[j]) {
values[k] = leftArr[i++];
} else {
values[k] = rightArr[j++];
}
bars[k].style.height = values[k] + "px";
bars[k].style.background = "#ff9800";
await sleep(speed);
bars[k].style.background = "linear-gradient(to top,#b88700,#ffd54d)";
k++;
}
while (i < leftArr.length) {
bars[k].style.background = "#ff9800";
values[k] = leftArr[i++];
bars[k].style.height = values[k] + "px";
await sleep(speed);
bars[k].style.background = "linear-gradient(to top,#b88700,#ffd54d)";
k++;
}
while (j < rightArr.length) {
bars[k].style.background = "#ff9800";
values[k] = rightArr[j++];
bars[k].style.height = values[k] + "px";
await sleep(speed);
bars[k].style.background = "linear-gradient(to top,#b88700,#ffd54d)";
k++;
}
}
randomize();
</script>
</body>
</html>
About this Component
Merge Sort is an efficient divide-and-conquer sorting algorithm that recursively divides an array into smaller halves until each subarray contains a single element. These smaller arrays are then merged back together in sorted order to produce the final sorted array. This interactive visualization lets you observe every split and merge operation in real time. You can randomize the array, adjust the animation speed, and understand how Merge Sort efficiently sorts large datasets by repeatedly combining sorted subarrays. Merge Sort has a guaranteed time complexity of O(n log n), making it significantly faster than simple algorithms like Bubble Sort, Selection Sort, and Insertion Sort for larger datasets. It is also a stable sorting algorithm, making it widely used in real-world applications.
Explore More Components
Discover more components from the Playground.



