Algorithm|Javascript Algorithm

Faster by Splitting and Merging: Merge Sort

0

Chris is feeling confident now. He was handling data quite efficiently with Insertion Sort.

Then one day, a request came from the company: "Sort 100,000 user logs by date."

Chris confidently ran Insertion Sort.

...1 second, 2 seconds, 10 seconds...

The browser froze again.

"Wait, I thought Insertion Sort was fast?"

"That's only when the data is nearly sorted! Running O(N^2) on 100,000 random items means 10 billion operations!"

Now we need to graduate from the "amateur league" of sorting and enter the pro league.

Regardless of how much data there is or how shuffled it is, we need the unwavering speed of O(N log N). The first runner in this category is the textbook definition of "Divide and Conquer": Merge Sort.

1. Divide and Conquer: "If it's hard, split it"

The idea behind Merge Sort is simple.

"Sorting 100,000 items is hard, but sorting 0 or 1 item is easy."

  • Split: Keep splitting the array in half. Until when? Until only one element remains.
  • Merge: Combine the split arrays back together. However, when combining, sort them in order.
  • Let's take the array [8, 3, 5, 1] as an example.

  • Split into [8, 3] and [5, 1].
  • Split into [8], [3], [5], [1]. (Splitting complete).
  • Compare [8] and [3] and merge \rightarrow [3, 8].
  • Compare [5] and [1] and merge \rightarrow [1, 5].
  • Compare [3, 8] and [1, 5] and merge \rightarrow [1, 3, 5, 8]. (Sorting complete!)
  • 2. Core Logic: Merging Two Sorted Arrays

    To implement Merge Sort, we first need a helper function that "combines two already sorted arrays into one."

    This process is like pointing with your fingers (pointers) at the front of two arrays and comparing them.

    javascript
    // Function to merge two sorted arrays (arr1, arr2)
    function merge(arr1, arr2) {
      let results = [];
      let i = 0; // Pointer for arr1
      let j = 0; // Pointer for arr2
    
      // While there are elements to compare in both arrays
      while (i < arr1.length && j < arr2.length) {
        if (arr2[j] > arr1[i]) {
          results.push(arr1[i]); // Push the smaller one to results
          i++; // Move pointer
        } else {
          results.push(arr2[j]);
          j++;
        }
      }
    
      // Handle remaining elements (Since they are already sorted, just push them all)
      while (i < arr1.length) {
        results.push(arr1[i]);
        i++;
      }
      while (j < arr2.length) {
        results.push(arr2[j]);
        j++;
      }
    
      return results;
    }
    
    // Test: merge([1, 10, 50], [2, 14, 99, 100])

    3. Completing with Recursion

    Now, we create the main sorting logic, mergeSort, using the merge function.

    We use recursion to keep splitting the array in half and then come back up while merging them.

    javascript
    function mergeSort(arr) {
      // 1. Base Case: If length is 1 or less, it's already sorted
      if (arr.length <= 1) return arr;
    
      // 2. Split in half
      let mid = Math.floor(arr.length / 2);
      let left = mergeSort(arr.slice(0, mid)); // Recursive call
      let right = mergeSort(arr.slice(mid));   // Recursive call
    
      // 3. Merge the sorted left and right, then return
      return merge(left, right);
    }
    
    mergeSort([10, 24, 76, 73, 72, 1, 9]);

    4. Performance Analysis: Why is it Fast?

  • Time Complexity: O(N log N) (Unconditionally fast)
  • Space Complexity: O(N) (Fatal Weakness)
  • Key Takeaways

  • Principle: Divide and Conquer. Split finely, then merge while sorting.
  • Time Complexity: O(N log N). Consistently fast regardless of data state.
  • Space Complexity: O(N). Consumes significant memory due to new array creation.
  • Feature: It is a Stable Sort, maintaining the order of equal values.

  • "It's fast, but it eats up too much memory?"

    Chris got greedy. Is there a dream algorithm that is fast with O(N log N) speed but doesn't use extra memory (O(1))?

    Of course, there is. But that guy is a bit 'unstable' and prickly.

    Let's go meet the King of sorting algorithms used most in the world, Quick Sort.

    🔗 References

  • VisuAlgo - Merge Sort
  • Merge Sort Implementation - GeeksforGeeks
  • Comments (0)

    0/1000 characters
    Loading comments...