forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmerge_sort.py
153 lines (118 loc) · 3.15 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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
"""
Merge Sort Algorithm
====================
This module implements the Merge Sort algorithm with three variations:
1. Recursive Merge Sort
2. Iterative Merge Sort
3. Merge Insertion Sort
Usage:
- Run this module directly for manual testing.
- Use doctests to verify correctness.
Example:
python merge_sort.py
"""
from typing import List
def merge_sort(arr: List[int]) -> List[int]:
"""
Perform merge sort on a list of integers.
Args:
arr: A list of integers.
Returns:
A sorted list of integers.
Example:
>>> merge_sort([8, 3, 5, 6])
[3, 5, 6, 8]
"""
if len(arr) > 1:
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
merge_sort(left_half)
merge_sort(right_half)
i = j = k = 0
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
arr[k] = left_half[i]
i += 1
else:
arr[k] = right_half[j]
j += 1
k += 1
while i < len(left_half):
arr[k] = left_half[i]
i += 1
k += 1
while j < len(right_half):
arr[k] = right_half[j]
j += 1
k += 1
return arr
def iterative_merge_sort(arr: List[int]) -> List[int]:
"""
Perform iterative merge sort on a list of integers.
Args:
arr: A list of integers.
Returns:
A sorted list of integers.
Example:
>>> iterative_merge_sort([8, 3, 5, 6])
[3, 5, 6, 8]
"""
if len(arr) <= 1:
return arr
width = 1
n = len(arr)
while width < n:
for i in range(0, n, 2 * width):
left = arr[i:i + width]
right = arr[i + width:i + 2 * width]
merged = merge(left, right)
arr[i:i + len(merged)] = merged
width *= 2
return arr
def merge(left: List[int], right: List[int]) -> List[int]:
"""
Merge two sorted lists into a single sorted list.
Args:
left: A sorted list of integers.
right: A sorted list of integers.
Returns:
A merged and sorted list of integers.
Example:
>>> merge([1, 3, 5], [2, 4, 6])
[1, 2, 3, 4, 5, 6]
"""
merged = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
merged.append(left[i])
i += 1
else:
merged.append(right[j])
j += 1
merged.extend(left[i:])
merged.extend(right[j:])
return merged
def merge_insertion_sort(arr: List[int]) -> List[int]:
"""
Perform merge insertion sort on a list of integers.
Args:
arr: A list of integers.
Returns:
A sorted list of integers.
Example:
>>> merge_insertion_sort([8, 3, 5, 6])
[3, 5, 6, 8]
"""
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = arr[:mid]
right = arr[mid:]
left = merge_insertion_sort(left)
right = merge_insertion_sort(right)
return merge(left, right)
if __name__ == "__main__":
import doctest
doctest.testmod()