28 February

Quick Sort Algorithm in JavaSript (pivot as the first element + pivot as the random element)

JavaScriptAlgorithms
Tutorial

Introduction


Quick Sort is one of the most famous and effective Sorting Algorithms. The comprehension of how it works will undoubtedly help you in your JavaScript learning. Also, questions on algorithms are popular in job interviews, so there is a big chance you will be asked to describe how Quick Sort works.

I’m sure that I convinced you that Quick Sort is important. Let’s start!



Basic knowledge for Quick Sort Implementation


At first, this lesson assumes that you know how to work with arrays, loops and know the array’s methods in JavaScript. If not, you can read about some information in the appropriate links. And after reading you can return to this article.

Arrays in JS: https://javascript.info/array
Loops in JS: https://javascript.info/while-for

Array’s methods which are used for the Quick Sort Implementation:


Implementation


Firstly, we need to write a function quickSort which will sort our array.

function quickSort(arr) {
  //code
}

Okay, let’s start to fill out the body of our function.

Quick Sort is an algorithm which implements recursively. And thus we need to add a base case for quickSort function.

function quickSort(arr) {
  if (arr.length < 2) return arr;
}

This string means that if the length is less than 2 we just return an array. We write it because we don’t need to sort an empty array or array with a single element.
The next step is to write the main variables which we need for our algorithm. There are pivot, left and right.

  • pivot — the element of the array (in our case is the first element) which is compared with other elements in the same array.
  • left — is an array that stores elements of the passed array which are less than the pivot.
  • right — the same as left, but stores elements greater or equal to the pivot.

Let’s add all of them to our function.

function quickSort(arr) {
  if (arr.length < 2) return arr;
  let pivot = arr[0];
  const left = [];
  const right = [];
}

Now we need to sort elements of the passed array in left and right arrays. This requires a for loop.

function quickSort(arr) {
  if (arr.length < 2) return arr;
  let pivot = arr[0];
  const left = [];
  const right = [];
    
  for (let i = 1; i < arr.length; i++) {
    if (pivot > arr[i]) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
}

Here we just check each element of the passed array and compare it with the pivot. When a for loop iterates through all elements our left array fills with elements less than the pivot and right — greater than the pivot. The method push here adds elements at the end of the left and right arrays.

Let’s look at the simple example with the following array:
[5, 2, 6, 1, 30, -10].

Pivot is the first element. It is 5. The algorithm compares each element after the pivot. It compares 5 and 2. 2 is less and 5 (2 < 5) and hence 2 is added to the left array. Then it compares 5 and 6. 6 is greater than 5 (6 > 5) and the algorithm adds 6 to the right array. And it does the same with the other elements.

Final left and right arrays will look as follows:

  • left: [2, 1, -10]
  • right: [6, 30]

But now you likely have a question: “And how does it help to sort the array?” The answer is simple. We need to call our quickSort function recursively on our left and right arrays and insert between them the pivot. Why? Because pivot is greater than elements of the left array and less than elements of the right array. And thus it must be between them in our final sorted array.

Okay, let’s return to our code. In order to return the final sorted array, we need to write the return and the something which we want to return. In our case it is:

  return quickSort(left).concat(pivot, quickSort(right));

In order to fully understand the Quick Sort Algorithm let’s continue with our example of [5, 2, 6, 1, 30, -10].

After one iteration we got the following result:

  • left: [2, 1, -10]
  • right: [6, 30]

Then the QuickSort algorithm does the operation of sorting with left [2, 1, -10] and right [6, 30] arrays. It means that our function will take 2 as the pivot of the left array and compare 1 and -10 with this pivot. And after it, we will get the following:

For left: [2, 1, -10]:

  • left: [1, -10]
  • right: []

For right: [6, 30]:

  • left: []
  • right: [30]

And it will be doing the same operation while will not achieve the true condition for already written string:

if (arr.length < 2) return arr;

In our example, there is only one array that doesn’t match this condition. It is left: [1, -10]. And now it will be iterated. Here is a result after the iteration:

For left: [1, -10] (pivot is 1):

  • left: [-10]
  • right: []

Yes, it’s cool! Now all our arrays match the appropriate condition. And after it, our quickSort function will return all these arrays with the help of the call stack. And in the final, our function will just return the sorted left array which will merge pivot and the sorted right array. The following line of code can tell us about this ( The concat() method is used to merge two or more arrays):

return quickSort(left).concat(pivot, quickSort(right));

Let’s look at the recursive stack of the left array. After it, your comprehension of the Quick Sort Algorithm will be advanced!
[5, 2, 6, 1, 30, -10]

left [2, 1, -10] & right [6, 30] (not touched in this example)

left [1, -10] & right []

left [-10] & right []
Note: the sign "" here is just for explanation. It isn’t the part of JavaScript

And when the left array riches an array with a single element [-10] the quickSort function will return results of the call stack. It will simply insert each pivot between the left and right arrays (pivot is highlighted in bold and underlined).

The sample: left + pivot + right (“+” = merge in this example).
[5, 2, 6, 1, 30, -10] (return [-10, 1, 2, 5, right array]])

left [2, 1, -10] (return [-10, 1, 2])

left [1, -10] & right [] (return [-10, 1])

left [-10] & right [] (return [-10])
The same operation will be for the right array:
[5, 2, 6, 1, 30, -10] (return [left array, 5, 6, 30]])

right: [6, 30] (return [6, 30])

left [] & right [30] (return [30])
And eventually:
return [left array(-10, 1, 2), pivot(5), right array(6, 30)]
Result: [-10, 1, 2, 5, 6, 30]

The Final code


The final code of the Quick Sort function:

function quickSort(arr) {
  if (arr.length < 2) return arr;
  let pivot = arr[0];
  const left = [];
  const right = [];
    
  for (let i = 1; i < arr.length; i++) {
    if (pivot > arr[i]) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat(pivot, quickSort(right));
}

Moreover, you can look at the .gif explanation from Wikipedia.

I don’t know about you, but it’s always been difficult for me to understand such graphical explanations of algorithms. And so I write this article with the hope that there will be people who are just like me.

image Taken from Wikipedia

And what about efficiency?


The average case for the Quick Sort Algorithm is O(n log n) where n is the length of an array. But the worst case is O(n²). You can look at the graph (X-axis is the number of elements in the array; Y-axis — operations or time)



In order to achieve the average case, we need to choose a random pivot each time. There are various implementations of Quick Sort with the random pivot but I usually do it so:

function quickSort(arr) {
  if (arr.length < 2) return arr;
  let min = 1;
  let max = arr.length - 1;
  let rand = Math.floor(min + Math.random() * (max + 1 - min));
  let pivot = arr[rand];
  const left = [];
  const right = [];
  arr.splice(arr.indexOf(pivot), 1);
  arr = [pivot].concat(arr);
  for (let i = 1; i < arr.length; i++) {
    if (pivot > arr[i]) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat(pivot, quickSort(right));
}

Note: if you want the explanation of this code just writes about it in the comments below. If I see that people want to know it I will publish a new article “Quick Sort with Random Pivot” in a wink.

Conclusion


I’m sure that after reading this article you fully understood the Quick Sort Algorithm and you will be confident in your job interview.

Moreover, if you want to plunge into algorithms learning I highly recommend you to read the book Aditya Bhargava “Grokking Algorithms”(taken from https://github.com/KevinOfNeu). It contains a lot of simple explanations of all popular algorithms.

Maybe you have much simpler explanation of the Quick Sort Algorithm in JS. Write about it in the comments!

Also if you want to get notifications about my new articles you can follow me in Medium and my Twitter account:


My social networks


If you have questions or you interested in my articles, you can check and subscribe on my social media:

Only registered users can participate in poll. Log in, please.
Do you know how to implement any of Sorting Algorithms (Quick Sort, Merge Sort, Bubble Sort, etc.)?
75% Yes, of course! 3
25% No, but I will learn one. 1
0% Bubble Sort in my heart! 0
4 users voted. 3 users abstained.
Tags: javascript algorithms big o quicksort
Hubs: JavaScript Algorithms
+3
1.2k 8
Comments 2
Ads
Top of the day