-
Notifications
You must be signed in to change notification settings - Fork 0
/
sort.py
164 lines (128 loc) · 4.32 KB
/
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
154
155
156
157
158
159
160
161
162
163
164
from math import ceil
from heapq import heapify, heappop
from util import timeit, merge, flat_map
from ADT import BST
from itertools import accumulate
from collections import Counter
RUN_SIZE = 2**6
@timeit
def quick_sort(array :list)->list:
def _quick_sort(array :list)->list:
if len(array)<=1: return array
pivot, is_bigger = array.pop(), lambda x: x>pivot
left_partition = _quick_sort([x for x in array if not is_bigger(x)])
right_partition = _quick_sort([x for x in array if is_bigger(x)])
return [*left_partition, pivot, *right_partition]
return _quick_sort(array)
@timeit
def merge_sort(array :list)->list:
def _merge_sort(array :list)->list:
length, mid = len(array), len(array)//2
if length <= 1: return array
left_subarray = _merge_sort(array[:mid])
right_subarray = _merge_sort(array[mid:])
return merge(left_subarray,right_subarray)
return _merge_sort(array)
@timeit
def tim_sort(array :list)->list:
run_num = ceil(len(array)/RUN_SIZE)
buckets = [[] for _ in range(run_num)]
for index in range(run_num):
start, stop = RUN_SIZE*index, RUN_SIZE*(index+1)
buckets[index] = _insertion_sort(array[start:stop])
return merge(*buckets)
@timeit
def tim_sort_recursive(array :list)->list:
return _tim_sort_recursive(array)
def _tim_sort_recursive(array :list)->list:
left = _insertion_sort(array[:RUN_SIZE])
if len(array)<RUN_SIZE: return left
right = _tim_sort_recursive(array[RUN_SIZE:])
return merge(left, right)
@timeit
def heap_sort(random_list: list)->list:
heapify(random_list)
result = []
while random_list:
result.append(heappop(random_list))
return result
@timeit
def bubble_sort(array :list)->list:
for y in range(1, len(array)):
swap: bool = False
for x in range(1,len(array)-(y-1)):
if array[x]<array[x-1]:
array[x],array[x-1], swap = array[x-1],array[x], True
if not swap: break
return array
@timeit
def insertion_sort(array :list)->list:
return _insertion_sort(array)
def _insertion_sort(array :list)->list:
for index in range(1,len(array)):
back=index-1
while back>=0 and array[back] > array[back+1]:
array[back], array[back+1] = array[back+1], array[back]
back-=1
return array
@timeit
def selection_sort(array :list)->list:
for idx_y, _ in enumerate(array):
min_idx = idx_y
for idx in range(idx_y,len(array)):
if array[idx] < array[min_idx]: min_idx = idx
array[min_idx], array[idx_y] = array[idx_y], array[min_idx]
return array
@timeit
def tree_sort(array: list)->list:
bst = BST().create_tree(array)
result = bst.inorder()
return result
@timeit
def shell_sort(array: list)->list:
return _shell_sort(array)
def _shell_sort(array: list)->list:
LENGTH, gap= len(array), len(array)//2
while gap>0:
for j in range(gap, LENGTH):
i=j-gap
while i>=0:
if array[i+gap]>array[i]: break
else: array[i+gap],array[i]=array[i],array[i+gap]
i=i-gap
gap=gap//2
return array
@timeit
def radix_sort(array :list)->list:
base, max_length = 10, len(str(max(array)))
for n in range(max_length):
bucket=[[] for _ in range(base)]
for item in array:
bucket[item//base**n%base].append(item)
array = flat_map(bucket)
return array
@timeit
def bucket_sort(array :list)->list:
BUCKET_SIZE = ceil(len(array)**(3/4))
min_val, max_val = min(array), max(array)
RANGE = (max_val-min_val+1)/BUCKET_SIZE
bucket = [[] for _ in range(BUCKET_SIZE)]
get_idx = lambda num: int((num-min_val)/RANGE)
for num in array:
bucket[get_idx(num)].append(num)
for x in bucket: _insertion_sort(x)
return flat_map(bucket)
@timeit
def counting_sort(array :list)->list:
count, result = [0 for _ in range(max(array)+1)], array[:]
for key, val in Counter(array).items():
count[key] = val
count = list(accumulate(count))
for num in array:
result[count[num]-1], count[num] = num, count[num]-1
return result
@timeit
def cube_sort(array :list)->list:
return array
def python_sort(random_list: list)->list:
return sorted(random_list)