Tell us what’s happening:
My implementation of bubble sort seems to give the correct sorted result but in comparison to the example it has one div too many, the first one with blue borders should have the starting array and then come the steps of the bubble sort, but it seems like in the example it starts highlighting the numbers one index to the right whereas my version starts from the first index so it ends with one too many steps.
Is this what is called an off-by-one error? I’ve been doing this test for 2 days and I am out of ideas, it seems to be close but I’m not sure where to tweak it as adding 1 to the j in highlightCurrentEls(div, j) would result in out of bounds error when comparing the second to last with the last element of the array.
Your code so far
<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Sorting Visualizer</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<div id="array-container">
<div id="starting-array"></div>
</div>
<div id="btn-container">
<button id="generate-btn" type="button">Generate Array</button>
<button id="sort-btn" type="button">Sort Array</button>
</div>
</main>
<script src="script.js"></script>
</body>
</html>
/* file: styles.css */
* {
box-sizing: border-box;
}
main {
height: 100vh;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
#array-container {
max-height: 95vh;
display: flex;
flex-direction: column;
flex-wrap: wrap;
gap: 2px;
}
#array-container>div {
min-width: 8rem;
height: 2rem;
box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
border-radius: 10px;
margin-bottom: 0.2rem;
border: 2px solid darkgray;
display: flex;
justify-content: space-evenly;
align-items: center;
}
#starting-array {
border: 4px solid darkblue !important;
}
#btn-container {
display: flex;
justify-content: space-around;
}
button {
padding: 2px;
margin: 5px;
}
span {
border-radius: 2px;
padding: 0.5px;
margin: 0
}
@media (min-width: 430px) {
#array-container>div {
min-width: 12rem;
}
span {
padding: 1px;
margin: 1px;
}
}
/* file: script.js */
const arrContainer = document.getElementById('array-container');
const startingArr = document.getElementById('starting-array');
const generateBtn = document.getElementById('generate-btn');
const sortBtn = document.getElementById('sort-btn');
function generateElement() {
const randInt = Math.floor((Math.random() * 100) + 1);
return randInt;
}
function generateArray() {
const randNums = [];
while (randNums.length <= 4) {
const randInt = generateElement();
randNums.push(randInt);
}
return randNums;
}
function generateContainer() {
let div = document.createElement('div');
div.innerHTML = '';
return div;
}
function fillArrContainer(element, arr) {
for (const integer of arr) {
let span = document.createElement('span');
span.innerHTML = integer;
span.setAttribute('id', `no-${integer}`)
element.appendChild(span);
}
return element;
}
function isOrdered(num1, num2) {
return num1 <= num2;
}
function swapElements(arr, index) {
const currNum = arr[index];
const nextNum = arr[index + 1];
if (!isOrdered(currNum, nextNum)) {
arr[index] = nextNum;
arr[index+1] = currNum;
return true;
}
return false;
}
function highlightCurrentEls(element, index) {
element.children[`${index}`].style.border = '1px dashed red';
element.children[`${index+1}`].style.border = '1px dashed red';
}
generateBtn.addEventListener('click', () => {
//clear sorted divs
const sortedDivs = arrContainer.querySelectorAll('.sorted-divs');
if (sortedDivs.length) {
Object.keys(sortedDivs).forEach((key) => {
sortedDivs[key].remove();
});
}
// fill startingArr with the generated array
startingArr.innerHTML = '';
const arr = generateArray();
const container = generateContainer();
const containedSpan = fillArrContainer(startingArr, arr);
})
sortBtn.addEventListener('click', () => {
// get array from the span elements
const spanEls = startingArr.children
let arr = Object.keys(spanEls).map((node) => {
return Number(spanEls[node].textContent)
});
arr = [85, 25, 64, 67, 79];
// highlighting startingArr
startingArr.innerHTML = '';
fillArrContainer(startingArr, arr);
highlightCurrentEls(startingArr, 0);
// nested loops for bubble sort
let swapped;
for (let i = 0; i < arr.length; i++) {
swapped = false;
for (let j = 0; j < (arr.length - 1); j++) {
if (swapElements(arr, j)) {
swapped = true;
}
const div = generateContainer();
fillArrContainer(div, arr);
highlightCurrentEls(div, j);
div.classList.add('sorted-divs');
arrContainer.appendChild(div);
}
if (!swapped) {
break;
}
}
// append sorted div
const lastDiv = generateContainer();
lastDiv.style.border = '2px solid green';
lastDiv.classList.add('sorted-divs');
fillArrContainer(lastDiv, arr);
arrContainer.appendChild(lastDiv);
})
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0
Challenge Information:
Build a Sorting Visualizer - Build a Sorting Visualizer

