-
Notifications
You must be signed in to change notification settings - Fork 0
/
qsort.py
122 lines (86 loc) · 2.83 KB
/
qsort.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
from random import randrange
from math import ceil, floor
def get_median(data: list, ) -> int:
base_index = randrange(0, len(data))
base_elem = data[base_index]
less = []
greater = []
meet_base_elem = False
for i in data:
if i < base_elem:
less.append(i)
else:
if i == base_elem and meet_base_elem:
greater.append(i)
elif i == base_elem and not meet_base_elem:
meet_base_elem = True
else:
greater.append(i)
if len(less) == floor(len(data) / 2) or len(less) == ceil(len(data) / 2):
return base_index
if len(less) > ceil(len(data) / 2):
return get_median(less)
if len(less) < floor(len(data) / 2):
return len(less) + get_median(greater)
# actually it works so slower than qsort that chose pivot item randomly (idk why)
def _qsort(data: list) -> list:
if len(data) == 0 or len(data) == 1:
return data
if len(data) == 2:
if data[0] > data[1]:
data[0], data[1] = data[1], data[0]
return data
base_index = get_median(data)
base_elem = data[base_index]
less = []
greater = []
meet_base_elem = False
for i in data:
if i < base_elem:
less.append(i)
else:
if i == base_elem and meet_base_elem:
greater.append(i)
elif i == base_elem and not meet_base_elem:
meet_base_elem = True
else:
greater.append(i)
return _qsort(less) + [base_elem] + _qsort(greater)
# this is main function, pls don't use another
def qsort(data: list) -> list:
if len(data) == 0 or len(data) == 1:
return data
if len(data) == 2:
if data[0] > data[1]:
data[0], data[1] = data[1], data[0]
return data
base_index = randrange(0, len(data))
base_elem = data[base_index]
less = []
greater = []
meet_base_elem = False
for i in data:
if i < base_elem:
less.append(i)
else:
if i == base_elem and meet_base_elem:
greater.append(i)
elif i == base_elem and not meet_base_elem:
meet_base_elem = True
else:
greater.append(i)
return qsort(less) + [base_elem] + qsort(greater)
if __name__ == '__main__':
from time import time
_1_time = 0
_2_time = 0
for _ in range(100):
nums = [randrange(1, 101) for _ in range(1001)]
start = time()
_1 = _qsort(nums)
_1_time += (time() - start)
start = time()
_2 = qsort(nums)
_2_time += (time() - start)
print(_1_time)
print(_2_time)