Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fc5cbde

Browse files
committed
Add a bottom up mergesort implementation
Refactor mergesorts merging behavior into a function to be reused for both bottom-up and top-down implementations.
1 parent 1a9f96a commit fc5cbde

File tree

1 file changed

+57
-33
lines changed

1 file changed

+57
-33
lines changed

sorting_algorithms.py

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -23,44 +23,32 @@ def sort(lo: int, hi: int):
2323
if arr[mid] <= arr[mid + 1]:
2424
return
2525

26-
# Copy the values to be merged in a temp array. Alternatively,
27-
# iterate over the original array and populate the temp array
28-
# with the sorted values, and copy the temp array back in sequence.
29-
temp_arr = arr[lo:hi + 1]
30-
31-
# Initialize the pointers needed to modify the original array.
32-
left_half_ptr = lo
33-
right_half_ptr = mid + 1
34-
original_arr_index = lo
35-
36-
# If both halves of the array have values left, compare their values
37-
# and merge back into the correct place in the original array.
38-
while left_half_ptr <= mid and right_half_ptr <= hi:
39-
if temp_arr[left_half_ptr - lo] <= temp_arr[right_half_ptr - lo]:
40-
arr[original_arr_index] = temp_arr[left_half_ptr - lo]
41-
left_half_ptr += 1
42-
else:
43-
arr[original_arr_index] = temp_arr[right_half_ptr - lo]
44-
right_half_ptr += 1
45-
46-
original_arr_index += 1
47-
48-
# One half of the array has run out of values, so just merge the
49-
# remaining values from the left or right half.
50-
while right_half_ptr <= hi:
51-
arr[original_arr_index] = temp_arr[right_half_ptr - lo]
52-
right_half_ptr += 1
53-
original_arr_index += 1
54-
55-
while left_half_ptr <= mid:
56-
arr[original_arr_index] = temp_arr[left_half_ptr - lo]
57-
left_half_ptr += 1
58-
original_arr_index += 1
26+
_merge(arr, lo, mid, hi)
5927

6028
sort(0, len(arr) - 1)
6129
return arr
6230

6331

32+
def bottom_up_mergesort(arr: List[float]) -> List[float]:
33+
arr_length = len(arr)
34+
curr_subarray_length = 1
35+
36+
# Continue until a merge encompasses the entire array.
37+
while curr_subarray_length < arr_length:
38+
39+
# Complete passes of {curr_subarray_len}-by-{curr_subarray_len} merges.
40+
for i in range(0, arr_length - curr_subarray_length, curr_subarray_length * 2):
41+
mid = (i + curr_subarray_length) - 1
42+
hi = min(mid + curr_subarray_length, arr_length - 1)
43+
_merge(arr, i, mid, hi)
44+
45+
# Double the size of the subarrays being merged after
46+
# each iteration through the array.
47+
curr_subarray_length *= 2
48+
49+
return arr
50+
51+
6452
def insertion_sort(arr: List[float]) -> List[float]:
6553
for i, curr_num in enumerate(arr):
6654
prev_elements_ptr = i - 1
@@ -90,3 +78,39 @@ def _subsequence_insertion_sort(arr: List[float], lo: int, hi: int) -> None:
9078
prev_elements_ptr -= 1
9179

9280
arr[prev_elements_ptr + 1] = current_num
81+
82+
83+
def _merge(arr: List[float], lo: int, mid: int, hi: int):
84+
# Copy the values to be merged in a temp array. Alternatively,
85+
# iterate over the original array and populate the temp array
86+
# with the sorted values, and copy the temp array back in sequence.
87+
temp_arr = arr[lo:hi + 1]
88+
89+
# Initialize the pointers needed to modify the original array.
90+
left_half_ptr = lo
91+
right_half_ptr = mid + 1
92+
original_arr_index = lo
93+
94+
# If both halves of the array have values left, compare their values
95+
# and merge back into the correct place in the original array.
96+
while left_half_ptr <= mid and right_half_ptr <= hi:
97+
if temp_arr[left_half_ptr - lo] <= temp_arr[right_half_ptr - lo]:
98+
arr[original_arr_index] = temp_arr[left_half_ptr - lo]
99+
left_half_ptr += 1
100+
else:
101+
arr[original_arr_index] = temp_arr[right_half_ptr - lo]
102+
right_half_ptr += 1
103+
104+
original_arr_index += 1
105+
106+
# One half of the array has run out of values, so just merge the
107+
# remaining values from the left or right half.
108+
while right_half_ptr <= hi:
109+
arr[original_arr_index] = temp_arr[right_half_ptr - lo]
110+
right_half_ptr += 1
111+
original_arr_index += 1
112+
113+
while left_half_ptr <= mid:
114+
arr[original_arr_index] = temp_arr[left_half_ptr - lo]
115+
left_half_ptr += 1
116+
original_arr_index += 1

0 commit comments

Comments
 (0)