🧊 Chillingly Efficient: A Deep Dive into Merge Sort 🔎
Tags: mergesort, sorting, algorithms, programming
Published: 2023-03-03 18:14:51

👋 Hey there! Are you tired of sorting through piles of data? 🤔 Merge Sort might just be the solution you're looking for! 🚀 In this post, we'll explore the ins and outs of this popular sorting algorithm 🤓 So buckle up and get ready to level up your sorting game! 🙌

When it comes to sorting, there are many algorithms out there. But one stands out for its efficiency and elegance: Merge Sort. 🤩

Merge Sort is a divide-and-conquer algorithm that works by recursively splitting the input array in half, sorting each half, and then merging the two halves back together. It is a very efficient algorithm with a time complexity of O(n log n) and a space complexity of O(n). 🙌

🤔 But how does Merge Sort work, you ask?

Well, it all starts with dividing the input array in half until each half contains only one element. At that point, we consider each half to be sorted. We then merge the two sorted halves back together by comparing the first element of each half and adding the smaller element to a new array. We repeat this process until all elements have been added to the new array in sorted order. 🤓

The merge operation is where the algorithm gets its name. It works by taking two sorted arrays and merging them into a single sorted array. To merge two sorted arrays, we start by comparing the first element of each array. The smaller of the two elements is added to the new array, and the comparison continues with the next element in the array that contained the smaller element. This process continues until one of the arrays is exhausted. At this point, the remaining elements in the other array are added to the new array. 🧐

🕰️ The time complexity of Merge Sort is O(n log n). This is because the algorithm recursively divides the input array into two halves until each half contains only one element. Sorting a single element array takes constant time. The merge operation that combines two sorted arrays takes linear time proportional to the sum of the sizes of the two arrays being merged. Since the input array is divided into halves log n times and each merge operation takes linear time, the total time complexity of Merge Sort is O(n log n). 🚀

💾 The space complexity of Merge Sort is O(n). This is because the algorithm creates temporary arrays to hold the two halves of the input array and the merged array during the merge operation. The size of the temporary arrays is proportional to the size of the input array. The algorithm uses a total of O(n) space during the entire sorting process. 

let's take a closer look at the Merge Sort algorithm and how it works.

Merge Sort is a divide-and-conquer algorithm, meaning that it breaks down a problem into smaller sub-problems, solves each sub-problem independently, and then combines the solutions to form the solution to the original problem. Specifically, Merge Sort works by recursively dividing an input array into two halves, sorting each half separately using Merge Sort, and then merging the two sorted halves back together to form a fully sorted array.

To illustrate how Merge Sort works, let's consider the following example input array:
`[38, 27, 43, 3, 9, 82, 10]
`
We can begin by dividing the input array in half to obtain two sub-arrays:
`[38, 27, 43, 3] [9, 82, 10]
`
We can then recursively apply the same process to each sub-array, continuing to divide the sub-arrays in half until each sub-array contains only one element:

`[38, 27] [43, 3] [9, 82] [10]
`

At this point, each sub-array is already sorted (since each sub-array contains only one element), so we can begin merging the sub-arrays back together. We start by merging the two leftmost sub-arrays `[38, 27]` and `[43, 3]`:

`[38, 27] [43, 3] -> [27, 38, 3, 43]
`
We can see that the two sub-arrays have been merged into a single sorted sub-array [27, 38, 3, 43]. We then merge the next two sub-arrays `[9, 82]` and `[10]`:

`[9, 82] [10] -> [9, 10, 82]
`
Again, we have merged the two sub-arrays into a single sorted sub-array `[9, 10, 82]`. Finally, we merge the two sorted sub-arrays `[27, 38, 3, 43]` and `[9, 10, 82]`:

`[27, 38, 3, 43] [9, 10, 82] -> [3, 9, 10, 27, 38, 43, 82]
`

And we have now obtained a fully sorted array `[3, 9, 10, 27, 38, 43, 82]`.

> 
![Merge Sort](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sltjiyb6omwe402d9bww.png)

Now, let's take a look at a C++ implementation of the Merge Sort algorithm:

> 

```
#include <iostream>
using namespace std;

void merge(int arr[], int left, int mid, int right) {
    int i, j, k;
    int n1 = mid - left + 1;
    int n2 = right - mid;
    int L[n1], R[n2];
    for (i = 0; i < n1; i++) {
        L[i] = arr[left + i];
    }
    for (j = 0; j < n2; j++) {
        R[j] = arr[mid + 1 + j];
    }
    i = 0;
    j = 0;
    k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

void mergeSort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

int main() {
    int arr[] = {38, 27, 43, 3, 9, 82, 10};
    int n = sizeof(arr) / sizeof(arr[0]);
    mergeSort(arr, 0, n - 1);
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
    return 0;
}

```
The `merge` function takes in an input array `arr`, and the leftmost and rightmost indices of two sub-arrays, and merges the sub-arrays back together in sorted order using the algorithm we described earlier. The `mergeSort` function takes in an input array arr, the leftmost and rightmost indices of the sub-array to be sorted, and recursively applies the Merge Sort algorithm to the sub-array until it is fully sorted. Finally, the `main` function defines an input array arr, sorts it using `mergeSort`, and prints the sorted array.

🤖 Merge Sort is widely used in many applications where sorting large datasets or maintaining the relative order of equal elements is important. It is especially useful when sorting linked lists, as it doesn't require random access to elements. Merge Sort is also a stable algorithm, which means that it preserves the relative order of equal elements in the input array. This property is useful in many applications, such as sorting data with multiple fields where one field is used as the primary sort key and another field is used as a secondary sort key. 🤓


In conclusion, Merge Sort is a very efficient and elegant sorting algorithm that works by dividing the input array into two halves, sorting each half recursively, and then merging the sorted halves back together. It has a time complexity of O(n log n) and a space complexity of O(n). Merge Sort is widely used in many applications where sorting large datasets or maintaining the relative order of equal elements is important. Give it a try next time you need to sort some data! 😎