sort an array
merge sort : recursion
[ while loop | slice | push | Math.floor | concat | length ]

Sort an array

Write a function, using the Merge Sort algorithm, that takes an array of numbers or an array of strings and returns the array sorted in ascending order. The original array will be unchanged.


Sorting algorithms are a set of instructions that takes an array or list as an input and arranges the items into a particular order.

Some sorting algorithms are more efficient than others.

The effectiveness of a sorting algorithm is usually defined by the following performance measures ↴

Time complexity the amount of time it takes for the algorithm to run.

Space complexity the amount of memory space it takes to perform the sorting based on an algorithm.


Merge Sort is a divide-and-conquer algorithm that splits the list into two halves, recursively sorts each half, and then merges the sorted halves back together. It is an efficient, stable, and comparison-based sorting algorithm.

Merge Sort has a time complexity of O(n log(n)) for all cases (worst, average, and best), where n is the number of elements in the list. This efficiency is due to the algorithm consistently dividing the list in half and merging sorted sublists.

Merge Sort has a space complexity of O(n) because it requires additional space to store the temporary sublists during the merging process.


Example ...

Enter an array ...

[10, 8, 4, 6, 2] original array

[2, 4, 6, 8, 10] array sorted in ascending order

The original array will be unchanged.

Arrays are used to store multiple values in a single variable.

Each value is called an element, and each element has a numeric position in the array, known as its index.

Arrays are zero-indexed, meaning the first element is at index 0, the second at index 1, and so on.

Arrays can contain any data type, including numbers, strings, and objects.

const arr1 = [2, 4, 6]; array

arr1[0]; element at index 0 → 2

arr1[1]; element at index 1 → 4

arr1[2]; element at index 2 → 6

arr1[3]; element at index 3 → undefined index not found


Strings are a sequence of zero or more characters written inside quotes used to represent text.

Strings may consist of letters, numbers, symbols, words, or sentences.

Strings are immutable, they cannot be changed.

Each character in a string has an index.

The first character will be index 0 the second character will be index 1 and so on.

There are two ways to access an individual character in a string.

charAt() method

const str1 = "abc"; string

str1.charAt(0); character at index 0 → "a"

str1.charAt(1); character at index 1 → "b"

str1.charAt(2); character at index 2 → "c"

str1.charAt(3); character at index 3 → "" index not found

Alternatively use at() or slice() methods

bracket notation []

const str2 = "abc"; string

str2[0]; character at index 0 → "a"

str2[1]; character at index 1 → "b"

str2[2]; character at index 2 → "c"

str2[3]; character at index 3 → undefined index not found


Numbers are used to represent both integer and floating-point values.

Numbers are most commonly expressed in literal forms like 255 or 3.14159 ↴

let num1 = 5; → number

let num2 = 2.5; → number

let num3 = num1 + num2;

console.log(num3); returns ↴

7.5 → number


Sort an array using the Merge Sort algorithm using ↴

recursion → programming technique where a function calls itself repeatedly to solve a problem.

while loop → repeatedly executes a block of code as long as a specified condition is true.

slice() method → returns selected elements in an array, as a new array.

push() method → adds specified elements to the end of an array and returns the new length of the array.

Math.floor() method → rounds a number down to the nearest integer.

concat() method → merge two or more arrays.

length property → set or return the number of elements in an array.


Recursion The act of a function calling itself.

Recursion is used to solve problems that contain smaller sub-problems.

A recursive function can receive two inputs: a base case (ends recursion) or a recursive case (resumes recursion).

Use recursion to find the factorial of 5.

let x = 5;

function factorial(num) {

if (num > 1) { Recursion call

return num * factorial(num - 1);

}

else { Base case

return 1;

};

}

call function

factorial(x); returns ↴

120 factorial of 5 → 120


while loop repeatedly executes a block of code as long as a specified condition evaluates to true.

while (condition) {

// execute code as long as condition is true

}

let x = 0; → counter

while (x < 4) {

console.log(x);

x++;

}

Initialize a counter variable x outside of the loop.

Condition x < 4 is checked before each iteration.

The loop will continue to run as long as x is less than 4

The loop repeatedly executes a block of code 4 times, from 0 to 3

For each iteration of the loop, the current value of x is printed to the console.

After each iteration, x is incremented by 1 x++

When x reaches 4 the condition evaluates to false, terminating the loop.

0

1

2

3 → printed to console


slice() method returns selected elements in an array, as a new array.

syntax ↴

slice(start) return a new array from start index to end of array

slice(start, end) return an array from start index to end index of array (exclusive).

Return a new array from index 1 to end of array.

const arr2 = [1, 2, 3, 4];

arr2.slice(1); start index is 1

returns ↴

[2, 3, 4]

Return a new array from index 1 to index 4 (exclusive).

const arr3 = [1, 2, 3, 4];

arr3.slice(1, 3); start index is 1 end index is 4 (not included)

returns ↴

[2, 3]


push() method adds new elements to the end of an array.

Add 4 to end of array.

const arr4 = [1, 2, 3];

arr4.push(4);

console.log(arr4); returns ↴

[1, 2, 3, 4]4 added to end of array

The push() method changes the length of the array.

arr4 is modified.

Using the spread operator creates a new array.

Add 4 to a new array.

const arr5 = [1, 2 , 3];

const arr6 = [...arr5, 4];

console.log(arr6); returns ↴

[1, 2, 3, 4]4 added to new array

console.log(arr5); returns ↴

[1, 2 ,3]

arr5 remains unchanged.


Math.floor() static method rounds down and returns the largest integer less than or equal to a given number.

console.log(Math.floor(9.99));9

console.log(Math.floor(5.50));5

console.log(Math.floor(3.14));3

console.log(Math.floor(99));99

console.log(Math.floor(-5.5));-6


concat() method is used to merge two or more arrays.

This method does not change the existing arrays, but instead returns a new array.

const arr7 = [1, 2, 3, 4, 5];

const arr8 = [4, 5, 6, 7, 8];

const arr9 = arr7.concat(arr8);

console.log(arr9); returns ↴

[1, 2, 3, 4, 5, 4, 5, 6, 7, 8] → values are not unique


length property returns the number of elements in an array.

const arr10 = [1, 2, 3, 4, 5, 6];

arr10.length; returns ↴

6 → there are 6 elements in the array


Initialize an array to sort.

const array1 = [10, 4, 8, 2, 6]; → user input


Define a function mergeSort() to sort an array.

function mergeSort(arr) {}

The function takes an array as input arr and returns a new array sorted in ascending order, using the Merge Sort algorithm.

The original array will be unchanged.

The Merge Sort algorithm is a very efficient divide and conquer algorithm.

It works by continuously splitting the array in half until it can no longer be divided.

Then, it merges each subarray while sorting them in the process.

This process continues until the whole array is sorted.

Recursion is a programming technique in which a function calls itself repeatedly until it reaches a certain condition. It is used to solve problems that can be broken down into smaller, simpler subproblems.

Base case halting point of the recursive function.

If the length of the array is 1 or less, it is already sorted; return the array as is and end execution of function.

if (arr.length <= 1) {

return arr

}

Recursive case

Find the middle index of the array, using Math.floor() method.

Math.floor(arr.length / 2)

Initialaize a variable to hold the value of the middle index of the array.

const mid = Math.floor(arr.length / 2) mid

Initialize an array to hold the elements while recursively sorting the left half.

const left = mergeSort(arr.slice(0, mid)) left

Initialize an array to hold the elements while recursively sorting the right half.

const right = mergeSort(arr.slice(mid)) right

Merge the sorted halves by calling the merge helper function.

return merge(left, right)

Define a helper function merge() to merge the two sorted arrays.

function merge(left, right) {}

The function takes the left and right arrays as an argument, sorts them, and returns a merged array.

Initialaize an array to hold the merged result.

const merged = [] merged

Initialize a pointer for the left array.

let leftIndex = 0 leftIndex

Initialize a pointer for the right array.

let rightIndex = 0 rightIndex

while loop repeatedly executes a block of code as long as a specified condition evaluates to true.

While loop runs as long as ...

leftIndex < left.length AND

rightIndex < right.length

while (leftIndex < left.length && rightIndex < right.length)

Compare elements from both arrays.

If left is less than right

if (left[leftIndex] < right[rightIndex])

Add smaller element to the merged array.

merged.push(left[leftIndex])

Move pointer in the left array.

leftIndex++ increment by 1

Else, if left is greater than right

Add smaller element to merged array.

merged.push(right[rightIndex])

Move pointer in the right array.

rightIndex++ increment by 1

Concatenate any remaining elements from both arrays and return merged array.

return merged

.concat(left.slice(leftIndex))

.concat(right.slice(rightIndex))


Call the function with ↴

mergeSort(array1);


Sort an array using the Merge Sort algorithm.

[2, 4, 3, 5, 1, 6] → unsorted array

unsorted array

[2, 4, 3, 5, 1, 6]

[2, 4, 3] [5, 1, 6]

[2] [4, 3] [5] [1, 6]

[2] [4] [3] [5] [1] [6]

[2, 3, 4] [1, 5, 6]

[1, 2, 3, 4, 5, 6]

sorted array


Sort an array using the Merge Sort algorithm.

const array1 = [2, 4, 3, 5, 1, 6];

function mergeSort(arr) {

if (arr.length <= 1) {

return arr;

}

const mid = Math.floor(arr.length / 2);

const left = mergeSort(arr.slice(0, mid));

const right = mergeSort(arr.slice(mid));

return merge(left, right); → call helper function

}

helper function

function merge(left, right) {

const merged = [];

let leftIndex = 0;

let rightIndex = 0;

while (leftIndex < left.length && rightIndex < right.length) {

if (left[leftIndex] < right[rightIndex]) {

merged.push(left[leftIndex]);

leftIndex++;

} else {

merged.push(right[rightIndex]);

rightIndex++;

}

}

return merged

.concat(left.slice(leftIndex))

.concat(right.slice(rightIndex));

}

call function

mergeSort(array1); returns ↴

[1, 2, 3, 4, 5, 6]


To sort a mixed numeric alphanumeric array ↴

Separate the strings and numbers into different arrays, sort them individually, and then merge them back together.

const arr1 = [1, 2, 3]; sorted numbers

const arr2 = ["a", "b", "c"]; sorted strings

const arr3 = [...arr1, ...arr2]; merge

console.log(arr3); returns ↴

[1, 2, 3, "a", "b", "c"]


Alternatives to sort order of array.

Change the comparison test ↴

left[leftIndex] < right[rightIndex] ⇡ ascending order

left[leftIndex] > right[rightIndex] ⇣ descending order

Sort an array