**Quick sort** is another sorting algorithm that allows you to sort values using a divide and conquer strategy, similar to the implementation of merge sort.

Just like its name implies, quick sort is relatively more efficient and faster than merge sort for small array size, but gradually lose its efficiency and speed on large array size.

To understand the implementation of quick sort, let’s start with a small example array as follows:

```
[6, 7, 3, 1, 5]
```

First, you need to pick one element as the **pivot** element. This element is usually the first or the last element of the array.

This example will pick the last element, which is `5`

. The elements of the array will then be sorted according to this pivot element. Elements smaller than `5`

will be placed to the left, while larger elements will be placed to the right:

```
[6, 7, 3, 1, 5]
[3, 1, 5, 6, 7]
```

Next, you will have to sort the elements on the **left side** and the **right side** of the pivot element, with each taking a new pivot value from the sub-arrays. From the example above, this means sorting two sub-arrays: `[3, 1]`

and `[6, 7]`

. During the third iteration, the position of `3`

and `1`

will be swapped so that the array is completely sorted:

```
[6, 7, 3, 1, 5]
[3, 1, 5, 6, 7]
[1, 3, 5, 6, 7]
```

Quick sort algorithm can be implemented recursively or iteratively. Let’s look at the recursive implementation first.

## Quick sort using recursive approach

To implement quick sort using the recursive approach, you need to first create a `partitioning()`

function that accepts the array (`arr`

) you wish to sort, the `startIndex`

, and the `endIndex`

of the array. The function will start by grabbing the `pivot`

element and compare the array elements with itself:

```
function partition(arr, startIndex, endIndex) {
const pivotVal = arr[endIndex]; // the pivot element
}
```

Then, you need to keep track of the array `index`

, which will take its value from the `startIndex`

. Each time a swap happens, the `index`

will move until it reaches the middle:

```
function partition(arr, startIndex, endIndex) {
const pivotVal = arr[endIndex]; // the pivot element
let index = startIndex;
}
```

It’s time to create the swapping algorithm. Let’s use a `for`

loop to iterate through the array from the `startIndex`

to the `endIndex`

. Each time an element is smaller than the `pivotVal`

element, you swap that element with the `index`

, then move the index up by one:

```
function partition(arr, startIndex, endIndex) {
const pivotVal = arr[endIndex]; // the pivot element
let index = startIndex;
// begin iterate and swap
for (let i = index; i < endIndex; i++) {
if (arr[i] < pivotVal) {
[arr[i], arr[index]] = [arr[index], arr[i]];
index += 1;
}
}
}
```

The swapping code above uses destructuring assignment to swap the elements. The logic happens as follows:

```
let a = 3;
let b = 10;
[a, b] = [b, a];
console.log(a, b); // a=10 b=3
```

The final step is to move the `pivotVal`

element to the current `index`

, because you need to place the pivot element in the middle of the array. After you move the `pivotVal`

, return the middle index, so that the sorting process can use the middle index to split the array to the left side and the right side:

```
function partition(arr, startIndex, endIndex) {
const pivotVal = arr[endIndex]; // the pivot element
let index = startIndex;
// begin iterate and swap
for (let i = index; i < endIndex; i++) {
if (arr[i] < pivotVal) {
[arr[i], arr[index]] = [arr[index], arr[i]];
index += 1;
}
}
// move `pivotVal` to the middle index and return middle index
[arr[index], arr[endIndex]] = [arr[endIndex], arr[index]];
return index;
}
```

With the `partition()`

function done, now you need to create the `quickSort()`

function. This function will simply call the `partition()`

function, passing along the `startIndex`

and `endIndex`

```
function quickSort(arr, startIndex, endIndex) {
// Base case or terminating case
if (startIndex >= endIndex) {
return;
}
// Returns midIndex / pivot index
let midIndex = partition(arr, startIndex, endIndex);
// Recursively apply the same logic to the left and right subarrays
quickSort(arr, startIndex, midIndex - 1);
quickSort(arr, midIndex + 1, endIndex);
}
```

And just like that, the `quickSort()`

function is done. You can test the function by sending an `array`

along with the `startIndex`

and `endIndex`

, which starts from `0`

and `array.length - 1`

:

```
let arr = [-2, 4, 6, 3, 7, 2];
quickSort(arr, 0, arr.length - 1);
console.log(arr); // [-2, 2, 3, 4, 6, 7]
```

Here’s the full code:

```
function partition(arr, startIndex, endIndex) {
const pivotVal = arr[endIndex]; // the pivot element
let index = startIndex;
// begin iterate and swap
for (let i = index; i < endIndex; i++) {
if (arr[i] < pivotVal) {
[arr[i], arr[index]] = [arr[index], arr[i]];
index += 1;
}
}
// move `pivotVal` to the middle index and return middle index
[arr[index], arr[endIndex]] = [arr[endIndex], arr[index]];
return index;
}
function quickSort(arr, startIndex, endIndex) {
// Base case or terminating case
if (startIndex >= endIndex) {
return;
}
// Returns midIndex / pivot index
let midIndex = partition(arr, startIndex, endIndex);
// Recursively apply the same logic to the left and right subarrays
quickSort(arr, startIndex, midIndex - 1);
quickSort(arr, midIndex + 1, endIndex);
}
let arr = [-2, 4, 6, 3, 7, 2];
quickSort(arr, 0, arr.length - 1);
console.log(arr); // [-2, 2, 3, 4, 6, 7]
```

Now that you know how to implement quick sort using JavaScript, it’s time to understand the time and space complexity of quick sort in Big O Notation.

## The efficiency of quick sort

The quick sort time complexity for the best-case is `O(logN)`

while the worst-case end up at `O(n²)`

. The Big O Notation always selects the worst-case as the measurement, so quick sort is not faster than merge sort in terms of time complexity.

Still, the quick sort used in-place algorithm to swap the elements, resulting in `O(N)`

in space complexity. Quick sort only needs extra space for storing the recursive calls.