Welcome to the beginner-friendly tutorial on building a Sorting Algorithm Visualizer! In this project, we'll create a visualizer that demonstrates algorithms like Bubble Sort, Quick Sort, and Merge Sort. This project will help you understand complex algorithms and visualize how they work.
Before we begin coding, let's set up a workspace for our project. This folder will be your digital canvas, where you'll keep all the project files organized.
Create a new folder on your computer to store all your project files. You can name it "sorting-visualizer".
On Windows:You'll need a text editor to write your code. We recommend Visual Studio Code, which is free and beginner-friendly.
We need three essential files for our project:
To create these files:
🎯 Success Check: You should now have:
👉 Tip: If something's not working, try restarting VS Code or creating the files using the "File → New File" menu.
Let's start by building the HTML structure for our visualizer. HTML is like the foundation of our app.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sorting Algorithm Visualizer</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Sorting Algorithm Visualizer</h1>
<div class="controls">
<select id="algorithm">
<option value="bubble">Bubble Sort</option>
<option value="quick">Quick Sort</option>
<option value="merge">Merge Sort</option>
</select>
<button id="generate">Generate Array</button>
<button id="sort">Sort</button>
</div>
<div id="bars-container"></div>
</div>
<script src="script.js"></script>
</body>
</html>
Let's break down the HTML structure:
<div class="container">
: The main container for our app.<h1>Sorting Algorithm Visualizer</h1>
: The title of our app.<div class="controls">
: The container for the control elements.<select id="algorithm">
: The dropdown for selecting the sorting algorithm.<button id="generate">Generate Array</button>
: The button to generate a random array.<button id="sort">Sort</button>
: The button to start the sorting process.<div id="bars-container"></div>
: The container for the bars representing the array elements.<script src="script.js"></script>
: Includes the JavaScript file for handling the app's functionality.Save your "index.html" file. Now we have the basic HTML structure in place. In the next step, we'll add some styling to make it look nice! 🎨
CSS is like the paint and brushes we use to make our app visually appealing. Let's add some styles to our visualizer.
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background-color: #fff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 800px;
text-align: center;
}
h1 {
margin: 0 0 20px;
font-size: 1.5rem;
}
.controls {
margin-bottom: 20px;
}
select, button {
padding: 10px;
margin: 0 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 1rem;
}
#bars-container {
display: flex;
justify-content: center;
align-items: flex-end;
height: 300px;
}
.bar {
background-color: #3498db;
margin: 0 1px;
width: 20px;
}
.bar.sorted {
background-color: #2ecc71;
}
.bar.comparing {
background-color: #e74c3c;
}
Let's understand the CSS rules we just added:
body
: Sets the default font, removes margins and padding, and centers the content on the screen..container
: Styles the container with a white background, padding, rounded corners, and a shadow.h1
: Styles the title with a larger font size and margin..controls
: Adds margin to the control elements.select, button
: Styles the select dropdown and buttons with padding, margin, border, and font size.#bars-container
: Uses flex layout to arrange the bars and sets the height of the container..bar
: Styles the bars with a blue background, margin, and width..bar.sorted
: Changes the background color of sorted bars to green..bar.comparing
: Changes the background color of comparing bars to red.Save your "styles.css" file. Now, if you open "index.html" in a web browser, you'll see the styled visualizer. 🎉
Now, let's add JavaScript to make our visualizer interactive! We'll handle user interactions and implement the sorting algorithms.
First, we need to select the HTML elements we want to work with. We'll select the control elements and the bars container.
// Selecting HTML elements
const algorithmSelect = document.getElementById('algorithm');
const generateButton = document.getElementById('generate');
const sortButton = document.getElementById('sort');
const barsContainer = document.getElementById('bars-container');
Here, we're using the getElementById
method to select the control elements and the bars container.
Next, let's create a function to generate a random array and display it as bars.
// Function to generate a random array
function generateArray() {
const array = [];
const arraySize = 50;
const maxBarHeight = 300;
for (let i = 0; i < arraySize; i++) {
const randomHeight = Math.floor(Math.random() * maxBarHeight) + 1;
array.push(randomHeight);
}
displayArray(array);
}
// Function to display the array as bars
function displayArray(array) {
barsContainer.innerHTML = '';
array.forEach((height, index) => {
const bar = document.createElement('div');
bar.classList.add('bar');
bar.style.height = `${height}px`;
bar.style.backgroundColor = '#3498db';
barsContainer.appendChild(bar);
});
}
The generateArray
function creates a random array of 50 elements with heights between 1 and 300. The displayArray
function displays the array as bars in the bars container.
Now, let's add event listeners to the buttons to handle user interactions.
// Adding event listeners to buttons
generateButton.addEventListener('click', generateArray);
sortButton.addEventListener('click', sortArray);
This code adds a click event listener to the "Generate Array" button, which calls the generateArray
function, and another event listener to the "Sort" button, which calls the sortArray
function.
Now, let's implement the sorting algorithms. We'll start with Bubble Sort.
// Function to perform Bubble Sort
async function bubbleSort(array) {
const n = array.length;
for (let i = 0; i < n - 1; i++) {
for (let j = 0; j < n - 1 - i; j++) {
const bar1 = barsContainer.children[j];
const bar2 = barsContainer.children[j + 1];
bar1.classList.add('comparing');
bar2.classList.add('comparing');
if (array[j] > array[j + 1]) {
[array[j], array[j + 1]] = [array[j + 1], array[j]];
await sleep(100);
displayArray(array);
}
bar1.classList.remove('comparing');
bar2.classList.remove('comparing');
}
}
array.forEach((_, index) => {
barsContainer.children[index].classList.add('sorted');
});
}
The bubbleSort
function implements the Bubble Sort algorithm and updates the display after each comparison and swap. The sleep
function is used to introduce a delay, making the sorting process visible.
Next, let's implement the Quick Sort algorithm.
// Function to perform Quick Sort
async function quickSort(array, left, right) {
if (left < right) {
const partitionIndex = await partition(array, left, right);
await quickSort(array, left, partitionIndex - 1);
await quickSort(array, partitionIndex + 1, right);
}
}
// Function to partition the array
async function partition(array, left, right) {
const pivot = array[right];
let i = left - 1;
for (let j = left; j < right; j++) {
const bar1 = barsContainer.children[j];
const bar2 = barsContainer.children[right];
bar1.classList.add('comparing');
bar2.classList.add('comparing');
if (array[j] < pivot) {
i++;
[array[i], array[j]] = [array[j], array[i]];
await sleep(100);
displayArray(array);
}
bar1.classList.remove('comparing');
bar2.classList.remove('comparing');
}
[array[i + 1], array[right]] = [array[right], array[i + 1]];
await sleep(100);
displayArray(array);
return i + 1;
}
The quickSort
function implements the Quick Sort algorithm recursively, and the partition
function is used to partition the array. The sleep
function is used to introduce a delay, making the sorting process visible.
Finally, let's implement the Merge Sort algorithm.
// Function to perform Merge Sort
async function mergeSort(array, left, right) {
if (left < right) {
const middle = Math.floor((left + right) / 2);
await mergeSort(array, left, middle);
await mergeSort(array, middle + 1, right);
await merge(array, left, middle, right);
}
}
// Function to merge two subarrays
async function merge(array, left, middle, right) {
const n1 = middle - left + 1;
const n2 = right - middle;
const L = array.slice(left, left + n1);
const R = array.slice(middle + 1, middle + 1 + n2);
let i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
const bar1 = barsContainer.children[k];
const bar2 = barsContainer.children[k + 1];
bar1.classList.add('comparing');
bar2.classList.add('comparing');
if (L[i] <= R[j]) {
array[k] = L[i];
i++;
} else {
array[k] = R[j];
j++;
}
await sleep(100);
displayArray(array);
bar1.classList.remove('comparing');
bar2.classList.remove('comparing');
k++;
}
while (i < n1) {
array[k] = L[i];
i++;
k++;
}
while (j < n2) {
array[k] = R[j];
j++;
k++;
}
await sleep(100);
displayArray(array);
}
The mergeSort
function implements the Merge Sort algorithm recursively, and the merge
function is used to merge two subarrays. The sleep
function is used to introduce a delay, making the sorting process visible.
Now, let's create a function to handle the "Sort" button click and call the appropriate sorting algorithm based on the selected algorithm.
// Function to handle the Sort button click
async function sortArray() {
const algorithm = algorithmSelect.value;
const array = Array.from(barsContainer.children).map(bar => parseInt(bar.style.height));
if (algorithm === 'bubble') {
await bubbleSort(array);
} else if (algorithm === 'quick') {
await quickSort(array, 0, array.length - 1);
} else if (algorithm === 'merge') {
await mergeSort(array, 0, array.length - 1);
}
array.forEach((_, index) => {
barsContainer.children[index].classList.add('sorted');
});
}
The sortArray
function determines the selected sorting algorithm and calls the appropriate sorting function. After sorting, it marks all bars as sorted.
Finally, let's add the sleep
function to introduce delays in the sorting process.
// Function to introduce a delay
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
The sleep
function returns a promise that resolves after the specified number of milliseconds, allowing us to introduce delays in the sorting process.
Now that we have the HTML, CSS, and JavaScript in place, let's put it all together and test our visualizer.
If everything is working correctly, you should be able to generate a random array and sort it using different sorting algorithms.
Congratulations! You've completed the Sorting Algorithm Visualizer project. You've learned how to create a visualizer that demonstrates complex sorting algorithms like Bubble Sort, Quick Sort, and Merge Sort. This project introduced you to working with algorithms, visualization, and web development.
Feel free to customize and expand your visualizer further. You can add more sorting algorithms, improve the design, or even create a mobile version. Happy coding and exploring the world of web development! 🚀