During one of my first technical interviews, where I applied for a Junior Frontend Developer role, I was given a bubble sort algorithm to solve. luckily, during that period I had been solving some basic questions on Data structure and algorithms, So I had a little idea of the structure of what was expected. I wasn't entirely sure of how to proceed, but I knew I needed two for loops and blah blah blah. So I started solving and after a few tries, I solved it. Note that this was a live coding session, and clearly the interviewer knew I was struggling a bit. After I successfully solved it, I was then asked to explain my code. I tried to but within myself, I knew the explanation wasn't clear enough and that wouldn't cut it. That was when I knew I didn't really understand what I was doing, I know the approach but the fact that I couldn't explain it meant I had some understanding to do.
So in this article, I want to try to explain the bubble sort algorithm to you in clear terms and I hope you find it useful. Also, I will ask that you first open the CodeSandbox embedded link below on a different tab, so that you can follow along as I explain the code line by line. go to the bubblesort.js file, that's where the code is.
Embedded from CodeSandbox
How bubble sort works
We compare two adjacent numbers in an array, we ask the question, is the first number bigger than the second number? if the answer is yes then the bigger number bubbles up(swapped with the smaller number). Note this happens when the array should be sorted in ascending order, but in cases where the array should be sorted in descending order, the smaller number bubbles up instead.
let's say we have an array of numbers that should be bubble sorted in ascending order, let's take this array as an example:bubblesort = [23, 0, 3234, 22, 111, 555, 33, 222]
From the array, what happens is, 23
and 0
will be compared together if 23 is bigger than 0, the two numbers will be swapped, so we will now have bubblesort = [0, 23, 3234, 22, 111, 555, 33, 222]
notice that 23 has now been bubbled up, next will be 23
and 3234
, the function will then again compare both numbers, notice that in this case, 23
is less than 3234
so no swap will happen in this case, the array will remain the same, the function now moves to the next two adjacent numbers, which is 3234
and 22
by now, you should already quess what will happen, since 3234
is greater than 22
, 3234
will be bubbled up, and this step will continue and because 3234
is greater than all the numbers in our array, it will continue to be swapped with the numbers it is compared with until it gets to the last number in the array which is 222
same thing will happen, since 3234
is greater than 222
, both numbers will swap positions, now making 3234
the last number in the array. you should have bubblesort = [0, 23, 22, 111, 555, 33, 222, 3234]
at this point, what I call the first pass has occurred. I hope I am not losing you at this point? Because this is where it get's interesting. The first pass, get's the largest number in an array to its correct position, the second pass will now get the second largest number to its right position.
First pass we had bubblesort = [0, 23, 22, 111, 555, 33, 222, 3234]
for the second pass, we have to start comparing numbers again from the beginning of the array, not the original array but the new array we got from the first pass which is bubblesort = [0, 23, 22, 111, 555, 33, 222, 3234]
just like we did during the first pass, 0
and 23
will be compared together to check which is greater, since 0
isn't greater than 23, no swap will happen, then 23
and 22
will be compared, since 23
is greater than 22
, they will both be swapped, and this will also continue until we get a new array which is bubblesort = [0, 22,23, 111, 33, 222, 555, 3234]
those this make sense now? I encourage you to get a pen and paper and write it down if you are still not getting it and follow the steps. If you are following along, this is what you should get in your different passes
First pass:
bubblesort = [0, 23, 22, 111, 555, 33, 222, 3234]
Second pass:
bubblesort = [0, 22,23, 111, 33, 222, 555, 3234]
third pass:
bubblesort = [0, 22,23, 33, 111, 222, 555, 3234]
fourth pass:
bubblesort = [0, 22,23, 33, 111, 222, 555, 3234]
fifth pass:
bubblesort = [0, 22,23, 33, 111, 222, 555, 3234]
sixth pass:
bubblesort = [0, 22,23, 33, 111, 222, 555, 3234]
seventh pass:
bubblesort = [0, 22,23, 33, 111, 222, 555, 3234]
In our case, because of the way our numbers were arranged, the array was already sorted after the third pass. So why didn't the function stop after the third pass since our array was already sorted? while that is because we told our function to go through the array arr.length - 1
times.
Let's explain our function line by line now
function bubbleSort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
Our first for loop is responsible for the number of passes, The reason why after the first pass, the function didn't just stop there is because of this loop, if the function had stopped at the first, the aim will not be achieved, because, at that point, the array wasn't sorted yet, we had only succeeded in sorting the largest number in the array to its position, we still had other numbers to sort.
for (var i = 0; i < arr.length - 1; i++)
var i = 0
here we initialised a variable i
before the loop starts, telling it to start from 0
because in programming counting starts from 0
instead of 1
. i < arr.length - 1
here we are telling the function not to exceed arr.length - 1
i
should be less than arr.length - 1
times. Since we had 8 numbers in our array, the function should go through the array 7 times, because we don't have to go through the array the last time.
i++
here we are telling the function to increase i
by one each time the code in the block is executed in other words, each time a pass is completed. so after the first pass, var i = 0
will increase to var i = 1
until it gets to var i = 7
when it get here, the code will be terminated since we told the function to stop at i < arr.length -1
For each pass, Our second for loop is responsible for making sure that after the first two adjacent numbers are compared, it doesn't stop there but also continues to compare the other numbers in the array, like in the case of our first pass, when 23
and 0
were compared and the swap was done, our for loop is responsible for making sure that 23
and 3234
and so on.
for (var j = 0; j < arr.length - 1 - i; j++)
var j = 0;
here j is initialized with a value of 0
as our starting point, j < arr.length - 1 - i;
is to ensure that the function doesn't go beyond the scope of the array and the - i
added means that, the current value of i
at every pass, should also be subtracted from the length of the iteration, we don't need to go through the whole array at every pass, and understandably so, because after the first pass we had the highest number in the array locked in its right position already, so no need comparing it with other numbers during other passes, and so on.
For j++
it means that, after the first two numbers are compared, increase the value of j
by 1
var j = 1;
the same thing happens when the second numbers are compared, j
will increase to var j = 2;
and since we have set a timeout, when j
gets to var j = 7;
it breaks from that loop and goes back to the first for loop. it is that simple.
Also, our second for loop also contains the function responsible for comparing two numbers and also the function for swapping them if the condition is met.
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
at this point, we are telling our function that, if the first number is less than the second number, do NOTHING but if the first number is greater than the second number that is to be compared, do the following:
- create a var
temp
and give it the value of the first number (Since the first number is greater) - then assign
arr[j]
toarr[j + 1]
- Finally, assign the new value of
arr[j + 1]
totemp
the swapped has happened. I hope this makes sense to you.
Another way to refactor the above code
function bubbleSort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
[ arr[j], arr[j+ 1] ] = [arr[j+ 1], arr[j] ] // swap there positions
}
}
}
return arr;
I really hope this makes sense to you and it helps you understand Bubble sort better.