-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmerge_sort.py
68 lines (61 loc) · 2.21 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
"""
Merge sort is an efficient, general-purpose, and comparison-based sorting algorithm.
Divine and Conquer paradigm. Time complexity: Θ(n log n).
Idea:
Разделение:
Делим массив arr на 2 подмассива длиной n / 2.
Властвование:
Рекурсивно сортируем эти 2 подмассива с использованием сортировки слиянием.
Комбинирование:
Сливаем такие два подмассива с помощью функции merge для получения окончательного
отсортированного ответа.
"""
def merge(left: list, right: list) -> list:
"""
Examples:
>>> merge([], [])
[]
>>> merge([0, 2, 5], [2, 3])
[0, 2, 2, 3, 5]
>>> merge([-5, -2], [-45, 5])
[-45, -5, -2, 5]
>>> merge(['ad', 'mer', 'ze'], ['an', 'g', 'zip'])
['ad', 'an', 'g', 'mer', 'ze', 'zip']
>>> merge(['17', '4', 'm'], ['2', 'da', 'ye'])
['17', '2', '4', 'da', 'm', 'ye']
"""
def _merge():
while left and right:
yield (left if left[0] <= right[0] else right).pop(0)
yield from left
yield from right
return list(_merge())
def merge_sort(arr: list) -> list:
"""
Examples:
>>> merge_sort([])
[]
>>> merge_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> merge_sort([-2, 5, -5, -45])
[-45, -5, -2, 5]
>>> merge_sort(['an', 'zip', 'ad', 'mer', 'g', 'ze'])
['ad', 'an', 'g', 'mer', 'ze', 'zip']
>>> merge_sort(['4', 'm', 'ye', 'da', '2', '17'])
['17', '2', '4', 'da', 'm', 'ye']
>>> import random
>>> arr = random.sample(range(-500, 500), 1000)
>>> merge_sort(arr) == sorted(arr)
True
>>> import string
>>> arr = random.choices(string.ascii_letters + string.digits, k=1000)
>>> merge_sort(arr) == sorted(arr)
True
"""
if len(arr) <= 1:
return arr
mid = len(arr) // 2
return merge(merge_sort(arr[:mid]), merge_sort(arr[mid:]))
if __name__ == "__main__":
import doctest
doctest.testmod()