02
Merge Sort Visualizer
Chapter 2 • Intermediate
90 min
Merge Sort Visualizer
Algorithm
Divide & Conquer Strategy:
- Divide: Split array into two halves
- Conquer: Recursively sort both halves
- Combine: Merge sorted halves
Implementation
python.js
def merge_sort(arr):
"""
Merge sort algorithm.
Time: O(n log n), Space: O(n)
"""
if len(arr) <= 1:
return arr
# Divide
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
# Conquer & Combine
return merge(left, right)
def merge(left, right):
"""Merge two sorted arrays"""
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
# Add remaining elements
result.extend(left[i:])
result.extend(right[j:])
return result
In-Place Merge Sort
python.js
def merge_sort_inplace(arr, left=0, right=None):
"""In-place merge sort"""
if right is None:
right = len(arr) - 1
if left < right:
mid = (left + right) // 2
merge_sort_inplace(arr, left, mid)
merge_sort_inplace(arr, mid + 1, right)
merge_inplace(arr, left, mid, right)
def merge_inplace(arr, left, mid, right):
"""Merge two sorted subarrays in-place"""
# Create temporary arrays
left_arr = arr[left:mid + 1]
right_arr = arr[mid + 1:right + 1]
i = j = 0
k = left
while i < len(left_arr) and j < len(right_arr):
if left_arr[i] <= right_arr[j]:
arr[k] = left_arr[i]
i += 1
else:
arr[k] = right_arr[j]
j += 1
k += 1
while i < len(left_arr):
arr[k] = left_arr[i]
i += 1
k += 1
while j < len(right_arr):
arr[k] = right_arr[j]
j += 1
k += 1
Complexity Analysis
- Time: O(n log n) - all cases
- Space: O(n) - for temporary arrays
- Stable: Yes
- In-place: No (standard version)
Recurrence Relation
T(n) = 2T(n/2) + O(n)
Using Master Theorem:
- a = 2, b = 2, f(n) = n
- log_b a = 1
- f(n) = Θ(n¹) = Θ(n^(log_b a))
- Case 2: T(n) = Θ(n log n)
Visual Trace
python.js
def merge_sort_trace(arr, depth=0):
"""Merge sort with trace output"""
indent = " " * depth
print(f"{indent}Sorting: {arr}")
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort_trace(arr[:mid], depth + 1)
right = merge_sort_trace(arr[mid:], depth + 1)
merged = merge(left, right)
print(f"{indent}Merged: {merged}")
return merged
Practice Problems
- Implement merge sort
- Count inversions using merge sort
- Merge K sorted arrays
- External merge sort for large files
- Optimize merge sort for nearly sorted arrays