forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mergesort.py
112 lines (87 loc) · 2.94 KB
/
mergesort.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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()