Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Merge Sort

What is Merge Sort?

Merge sort is a classic Divide and Conquer sorting algorithm. It recursively splits the array into halves until each half has one element (trivially sorted), then merges the sorted halves back together. It guarantees O(n log n) in all cases.

CaseTimeSpaceStable?
Best / Average / WorstO(n log n)O(n)Yes

How it Works

For array [38, 27, 43, 3, 9, 82, 10]:

  • Divide: [38,27,43,3] | [9,82,10] → [38,27] | [43,3] | [9,82] | [10] → [38] | [27] | [43] | [3] | [9] | [82] | [10]
  • Merge: [27,38] | [3,43] | [9,82] | [10] → [3,27,38,43] | [9,10,82] → [3,9,10,27,38,43,82] ✓
Merge Sort — Full Implementation
import java.util.Arrays;

public class MergeSort {

    // Main sort function — DIVIDE step
    static void mergeSort(int[] arr, int left, int right) {
        if (left >= right) return;  // base case: 0 or 1 element

        int mid = left + (right - left) / 2;  // avoid overflow
        mergeSort(arr, left, mid);             // sort left half
        mergeSort(arr, mid + 1, right);        // sort right half
        merge(arr, left, mid, right);          // COMBINE step
    }

    // Merge two sorted subarrays arr[left..mid] and arr[mid+1..right]
    static void merge(int[] arr, int left, int mid, int right) {
        int n1 = mid - left + 1;
        int n2 = right - mid;

        // Create temp arrays
        int[] L = new int[n1];
        int[] R = new int[n2];

        for (int i = 0; i < n1; i++) L[i] = arr[left + i];
        for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j];

        // Merge back into arr
        int i = 0, j = 0, k = left;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) arr[k++] = L[i++];
            else               arr[k++] = R[j++];
        }
        while (i < n1) arr[k++] = L[i++];
        while (j < n2) arr[k++] = R[j++];
    }

    // Count inversions using merge sort (bonus)
    static long countInversions(int[] arr, int left, int right) {
        long count = 0;
        if (left < right) {
            int mid = (left + right) / 2;
            count += countInversions(arr, left, mid);
            count += countInversions(arr, mid + 1, right);
            count += mergeCount(arr, left, mid, right);
        }
        return count;
    }

    static long mergeCount(int[] arr, int left, int mid, int right) {
        int[] L = Arrays.copyOfRange(arr, left, mid + 1);
        int[] R = Arrays.copyOfRange(arr, mid + 1, right + 1);
        int i = 0, j = 0, k = left;
        long count = 0;
        while (i < L.length && j < R.length) {
            if (L[i] <= R[j]) arr[k++] = L[i++];
            else { arr[k++] = R[j++]; count += L.length - i; }
        }
        while (i < L.length) arr[k++] = L[i++];
        while (j < R.length) arr[k++] = R[j++];
        return count;
    }

    public static void main(String[] args) {
        int[] arr = {38, 27, 43, 3, 9, 82, 10};
        System.out.println("Before: " + Arrays.toString(arr));
        mergeSort(arr, 0, arr.length - 1);
        System.out.println("After:  " + Arrays.toString(arr));
        // After: [3, 9, 10, 27, 38, 43, 82]

        int[] inv = {2, 4, 1, 3, 5};
        System.out.println("Inversions: " + countInversions(inv, 0, inv.length - 1));  // 3
    }
}

/*
 * Recurrence: T(n) = 2T(n/2) + O(n)
 * Master Theorem Case 2: T(n) = O(n log n)
 *
 * Advantages:
 * - Guaranteed O(n log n) — no worst case like Quick Sort
 * - Stable sort — preserves relative order of equal elements
 * - Good for linked lists (no random access needed)
 *
 * Disadvantage:
 * - O(n) extra space for temporary arrays
 */

Merge Sort Advantages and Disadvantages

AdvantagesDisadvantages
Guaranteed O(n log n) — no worst caseO(n) extra space for temporary arrays
Stable sort — preserves relative order of equal elementsSlower than Quick Sort in practice (cache misses)
Excellent for linked lists (no random access needed)Not in-place
Parallelizable — subproblems are independentOverkill for small arrays
Used in external sorting (data too large for RAM)—

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.