mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-30 16:31:08 +00:00
cecf43d648
* Pyupgrade to Python 3.9 * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
113 lines
2.9 KiB
Python
113 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
|
|
def merge(left_half: list, right_half: list) -> list:
|
|
"""Helper function for mergesort.
|
|
|
|
>>> left_half = [-2]
|
|
>>> right_half = [-1]
|
|
>>> merge(left_half, right_half)
|
|
[-2, -1]
|
|
|
|
>>> left_half = [1,2,3]
|
|
>>> right_half = [4,5,6]
|
|
>>> merge(left_half, right_half)
|
|
[1, 2, 3, 4, 5, 6]
|
|
|
|
>>> left_half = [-2]
|
|
>>> right_half = [-1]
|
|
>>> merge(left_half, right_half)
|
|
[-2, -1]
|
|
|
|
>>> left_half = [12, 15]
|
|
>>> right_half = [13, 14]
|
|
>>> merge(left_half, right_half)
|
|
[12, 13, 14, 15]
|
|
|
|
>>> left_half = []
|
|
>>> right_half = []
|
|
>>> merge(left_half, right_half)
|
|
[]
|
|
"""
|
|
sorted_array = [None] * (len(right_half) + len(left_half))
|
|
|
|
pointer1 = 0 # pointer to current index for left Half
|
|
pointer2 = 0 # pointer to current index for the right Half
|
|
index = 0 # pointer to current index for the sorted array Half
|
|
|
|
while pointer1 < len(left_half) and pointer2 < len(right_half):
|
|
if left_half[pointer1] < right_half[pointer2]:
|
|
sorted_array[index] = left_half[pointer1]
|
|
pointer1 += 1
|
|
index += 1
|
|
else:
|
|
sorted_array[index] = right_half[pointer2]
|
|
pointer2 += 1
|
|
index += 1
|
|
while pointer1 < len(left_half):
|
|
sorted_array[index] = left_half[pointer1]
|
|
pointer1 += 1
|
|
index += 1
|
|
|
|
while pointer2 < len(right_half):
|
|
sorted_array[index] = right_half[pointer2]
|
|
pointer2 += 1
|
|
index += 1
|
|
|
|
return sorted_array
|
|
|
|
|
|
def merge_sort(array: list) -> list:
|
|
"""Returns a list of sorted array elements using merge sort.
|
|
|
|
>>> from random import shuffle
|
|
>>> array = [-2, 3, -10, 11, 99, 100000, 100, -200]
|
|
>>> shuffle(array)
|
|
>>> merge_sort(array)
|
|
[-200, -10, -2, 3, 11, 99, 100, 100000]
|
|
|
|
>>> shuffle(array)
|
|
>>> merge_sort(array)
|
|
[-200, -10, -2, 3, 11, 99, 100, 100000]
|
|
|
|
>>> array = [-200]
|
|
>>> merge_sort(array)
|
|
[-200]
|
|
|
|
>>> array = [-2, 3, -10, 11, 99, 100000, 100, -200]
|
|
>>> shuffle(array)
|
|
>>> sorted(array) == merge_sort(array)
|
|
True
|
|
|
|
>>> array = [-2]
|
|
>>> merge_sort(array)
|
|
[-2]
|
|
|
|
>>> array = []
|
|
>>> merge_sort(array)
|
|
[]
|
|
|
|
>>> array = [10000000, 1, -1111111111, 101111111112, 9000002]
|
|
>>> sorted(array) == merge_sort(array)
|
|
True
|
|
"""
|
|
if len(array) <= 1:
|
|
return array
|
|
# the actual formula to calculate the middle element = left + (right - left) // 2
|
|
# this avoids integer overflow in case of large N
|
|
middle = 0 + (len(array) - 0) // 2
|
|
|
|
# Split the array into halves till the array length becomes equal to One
|
|
# merge the arrays of single length returned by mergeSort function and
|
|
# pass them into the merge arrays function which merges the array
|
|
left_half = array[:middle]
|
|
right_half = array[middle:]
|
|
|
|
return merge(merge_sort(left_half), merge_sort(right_half))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import doctest
|
|
|
|
doctest.testmod()
|