Merge Sort
Idea
- Uses divide and conquer paradigm
- Divides array into two halves, recursively sorts them, then merges
- Stable sorting algorithm that maintains relative order of equal elements
- Guaranteed O(n log n) performance regardless of input data
Visualization
How It Works
Divide Phase:
- Recursively divide the array into two halves
- Continue dividing until each subarray has one element
- Single element arrays are considered sorted
Merge Phase:
- Merge pairs of sorted subarrays to create larger sorted arrays
- Compare elements from both arrays and place smaller one first
- Continue until all elements are merged
- Use temporary arrays to store intermediate results
Example Process:
Original: [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]
Implementation
public class MergeSort {
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
// Sort first and second halves
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// Merge the sorted halves
merge(arr, left, mid, right);
}
}
private static void merge(int[] arr, int left, int mid, int right) {
// Create temporary arrays
int[] leftArray = new int[mid - left + 1];
int[] rightArray = new int[right - mid];
// Copy data to temporary arrays
for (int i = 0; i < leftArray.length; i++) {
leftArray[i] = arr[left + i];
}
for (int i = 0; i < rightArray.length; i++) {
rightArray[i] = arr[mid + 1 + i];
}
// Merge the temporary arrays back
int i = 0, j = 0, k = left;
while (i < leftArray.length && j < rightArray.length) {
if (leftArray[i] <= rightArray[j]) {
arr[k] = leftArray[i];
i++;
} else {
arr[k] = rightArray[j];
j++;
}
k++;
}
// Copy remaining elements if any
while (i < leftArray.length) {
arr[k] = leftArray[i];
i++;
k++;
}
while (j < rightArray.length) {
arr[k] = rightArray[j];
j++;
k++;
}
}
}
Time and Space Analysis
- Time Complexity:
- Best Case: O(n log n)
- Average Case: O(n log n)
- Worst Case: O(n log n)
- Space Complexity: O(n) for temporary arrays
Properties
- Stable sorting algorithm
- Not in-place (requires extra space)
- Divide and conquer algorithm
- Predictable performance (always O(n log n))
- Parallelizable (different parts can be sorted concurrently)
Use Cases
- When stable sort is needed
- When predictable performance is required
- External sorting (sorting large files)
- When data is in linked lists (no random access needed)
- Parallel processing environments
Advantages
- Stable sorting algorithm
- Guaranteed O(n log n) performance
- Parallelizable
- Works well with linked lists
Disadvantages
- Requires O(n) extra space
- Overkill for small arrays
- Not cache friendly in basic implementation
Variants
- Bottom-up merge sort (iterative version)
- Natural merge sort
- Parallel merge sort
- In-place merge sort (complex but possible)