Merge Sort is one of the most efficient sorting algorithms, with a time complexity of O(n log n). It works by dividing the input array into two halves, sorting each half, and then merging them back together. In this guide, we'll explore how Merge Sort works step by step, with Python code examples to help clarify the process.
What Is Merge Sort
Merge Sort is a divide and conquer algorithm. The core idea behind this algorithm is to break the problem into smaller sub-problems (sorting smaller arrays) and then combine the solutions to solve the larger problem (sorting the entire array).
Steps of Merge Sort:
- Divide: Split the array into two halves.
- Conquer: Recursively sort both halves.
- Merge: Combine the two sorted halves into one sorted array.
How Does Merge Sort Work
Here’s how the algorithm works in a more detailed breakdown:
- Splitting the Array: The array is split into two halves, recursively, until each subarray contains only one element. A single-element array is considered sorted by default.
- Merging the Arrays: After the division, the algorithm starts merging the subarrays back together, while sorting them. This merge step is crucial and requires careful comparison of elements from the two subarrays.
Merge Sort Algorithm In Python
Let's implement Merge Sort in Python.
pythondef merge_sort(arr): # Base case: array with less than 2 elements is already sorted if len(arr) <= 1: return arr # Step 1: Divide the array into two halves mid = len(arr) // 2 left_half = arr[:mid] right_half = arr[mid:] # Step 2: Recursively sort both halves left_sorted = merge_sort(left_half) right_sorted = merge_sort(right_half) # Step 3: Merge the two sorted halves return merge(left_sorted, right_sorted) def merge(left, right): sorted_array = [] i = j = 0 # Compare elements from both subarrays and add the smallest element while i < len(left) and j < len(right): if left[i] < right[j]: sorted_array.append(left[i]) i += 1 else: sorted_array.append(right[j]) j += 1 # Add the remaining elements from either left or right subarray sorted_array.extend(left[i:]) sorted_array.extend(right[j:]) return sorted_array
Key Features Of Merge Sort
Time Complexity: O(n log n)
The time complexity of Merge Sort is O(n log n). The log n
factor comes from the fact that we split the array in half at each recursive step, and the n
factor comes from merging all the elements back together.
Space Complexity: O(n)
Merge Sort requires additional space to hold the left and right subarrays, leading to a space complexity of O(n). While the algorithm is efficient in terms of time, its space complexity can be a drawback compared to other sorting algorithms like QuickSort.
Why Use Merge Sort
- Stable Sorting: Merge Sort preserves the relative order of records with equal keys.
- Guaranteed Time Complexity: Unlike QuickSort, which has a worst-case time complexity of O(n^2), Merge Sort consistently runs in O(n log n) time, making it a reliable option for large datasets.
- External Sorting: Merge Sort is ideal for sorting large datasets that don’t fit into memory since it works well with external storage.
Merge Sort in Action
Let’s run the algorithm with a sample array to see how it works:
pythonarr = [38, 27, 43, 3, 9, 82, 10] sorted_arr = merge_sort(arr) print(sorted_arr)
Output:
[3, 9, 10, 27, 38, 43, 82]
As you can see, Merge Sort effectively sorts the array in ascending order.
Conclusion
Merge Sort is a powerful algorithm with guaranteed O(n log n) performance, making it one of the best choices for sorting large datasets. Though it may require additional space for the subarrays, its stability and consistent time complexity make it a popular choice in many applications. If you're working with large datasets or need a stable sorting algorithm, Merge Sort is an excellent option to consider.
By following this guide, you should now have a solid understanding of how Merge Sort works and how to implement it in Python. Happy coding!