```
"""
This is a pure Python implementation of the merge sort algorithm.
For doctests run following command:
python -m doctest -v merge_sort.py
or
python3 -m doctest -v merge_sort.py
For manual testing run:
python merge_sort.py
"""
def merge_sort(collection: list) -> list:
"""
Sorts a list using the merge sort algorithm.
:param collection: A mutable ordered collection with comparable items.
:return: The same collection ordered in ascending order.
Time Complexity: O(n log n)
Examples:
>>> merge_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> merge_sort([])
[]
>>> merge_sort([-2, -5, -45])
[-45, -5, -2]
"""
def merge(left: list, right: list) -> list:
"""
Merge two sorted lists into a single sorted list.
:param left: Left collection
:param right: Right collection
:return: Merged result
"""
result = []
while left and right:
result.append(left.pop(0) if left[0] <= right[0] else right.pop(0))
result.extend(left)
result.extend(right)
return result
if len(collection) <= 1:
return collection
mid_index = len(collection) // 2
return merge(merge_sort(collection[:mid_index]), merge_sort(collection[mid_index:]))
if __name__ == "__main__":
import doctest
doctest.testmod()
try:
user_input = input("Enter numbers separated by a comma:\n").strip()
unsorted = [int(item) for item in user_input.split(",")]
sorted_list = merge_sort(unsorted)
print(*sorted_list, sep=",")
except ValueError:
print("Invalid input. Please enter valid integers separated by commas.")
```

Given an array of n elements, write a function to sort the array

- Find a mid point and divide the array into to halves based on the mid point
- Recursively call the merge sort function for both the halves
- Merge the two sorted halves to get the sorted array

```
Best case - O(n log n)
Average - O(n log n)
Worst case - O(n log n)
```

`O(n)`

```
arr = [1, 3, 9, 5, 0, 2]
Divide the array in two halves [1, 3, 9] and [5, 0, 2]
Recursively call merge sort function for both these halves which will provide sorted halves
=> [1, 3, 9] & [0, 2, 5]
Now merge both these halves to get the sorted array [0, 1, 2, 3, 5, 9]
```

```
arr = [1, 9, 2, 5, 7, 3, 6, 4]
Divide the array into two halves [1, 9, 2, 5] and [7, 3, 6, 4]
As you can see that the above two halves are not yet sorted, so divide both of them into two halves again.
This time we get four arrays as [1, 9], [2, 5], [7, 3] and [6, 4].
We see that the last two arrays are again not sorted, so we divide them again into two halves and we will get [7], [3], [6], and [4].
Since an array of a single element is sorted, we now have all the arrays sorted, now we only need to merge them appropriately.
First, the arrays of one element will be merged as they were divided in last, and are at top of the recursion stack, so we get [3,7] and [4,6].
Now the merge will occur accordingly to the recursion stack, [1, 9] and [2, 5] will be merged and will make [1, 2, 5, 9].
Similarly [3, 7] and [4, 6] will be merged and made [3, 4, 6, 7].
At the next stack level [1, 2, 5, 9] and [3, 4, 6, 7] will be merged and we will get the final sorted array as [1, 2, 3, 4, 5, 6, 7, 9].
```