-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmerge_sort.py
96 lines (71 loc) · 2.29 KB
/
merge_sort.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
array = [8, 5, 2, 9, 5, 6, 3]
# O(n*log(n)) time | O(n*log(n)) space
def merge_sort(arr):
if len(arr) == 1:
return arr
middle_idx = len(arr) // 2
left_half = arr[:middle_idx]
right_half = arr[middle_idx:]
return merge_sorted_arrays(merge_sort(left_half), merge_sort(right_half))
def merge_sorted_arrays(left_half, right_half):
sorted_array = [None for i in range(len(left_half) + len(right_half))]
"""
k - current index in a sorted array
i - current index in a left half
j - current index in a right half
"""
k = i = j = 0
while i < len(left_half) and j < len(right_half):
if left_half[i] <= right_half[j]:
sorted_array[k] = left_half[i]
i += 1
else:
sorted_array[k] = right_half[j]
j += 1
k += 1
while i < len(left_half):
sorted_array[k] = left_half[i]
i += 1
k += 1
while j < len(right_half):
sorted_array[k] = right_half[j]
j += 1
k += 1
return sorted_array
print('merge sort', merge_sort(array))
# O(n*log(n)) time | O(n) space
def merge_sort_in_place(arr):
if len(arr) <= 1:
return arr
auxiliary_arr = arr[:]
merge_sort_helper(arr, auxiliary_arr, 0, len(arr) - 1)
return arr
def merge_sort_helper(main_arr, auxiliary_arr, start_idx, end_idx):
if start_idx == end_idx:
return
middle_idx = (start_idx + end_idx) // 2
merge_sort_helper(auxiliary_arr, main_arr, start_idx, middle_idx)
merge_sort_helper(auxiliary_arr, main_arr, middle_idx + 1, end_idx)
do_merge(main_arr, auxiliary_arr, start_idx, middle_idx, end_idx)
def do_merge(main_arr, auxiliary_arr, start_idx, middle_idx, end_idx):
k = start_idx
i = start_idx
j = middle_idx + 1
while i <= middle_idx and j <= end_idx:
if auxiliary_arr[i] <= auxiliary_arr[j]:
main_arr[k] = auxiliary_arr[i]
i += 1
else:
main_arr[k] = auxiliary_arr[j]
j += 1
k += 1
while i <= middle_idx:
main_arr[k] = auxiliary_arr[i]
i += 1
k += 1
while j <= end_idx:
main_arr[k] = auxiliary_arr[j]
j += 1
k += 1
print('original array', array)
print('merge sort in place', merge_sort_in_place(array))