mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-30 16:31:08 +00:00
de2725f4ac
* Update mergesort.py 1) Updating the merge sort in python as the previous implementation was modifying the input array 2) divided the division part and conquer part of the merge sort algorithm as 2 functions namely mergeSort and merge. 3) function mergeSort divides the function into halves i.e the purpose of the function will be to divide the array 4) function merge will merge 2 halves into a sorted array 5)Added random test cases using shuffle as suggested by @dhruvmanila 6 The time and space complexity of the previous and my version remains the same. i.e (n log(n) time and n log(n) space 7) changed variables as per the python case as required and suggested by @dhruvmanila 8) Updated function names as suggested by @dhurvmanila * Update mergesort.py Added in few more test cases added type hints for the functions and parameters as suggested by @dhruvmanila formatted the code using Auto Pep8 * Update mergesort.py update and added new testcases * Update mergesort.py Added in doc test in merge function * Update mergesort.py fixing pre-commit fails * Update mergesort.py Co-authored-by: Dhruv <dhruvmanila@gmail.com>
113 lines
2.9 KiB
Python
113 lines
2.9 KiB
Python
from typing import List
|
|
|
|
|
|
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()
|