-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathquick_sort.py
More file actions
142 lines (107 loc) · 3.72 KB
/
quick_sort.py
File metadata and controls
142 lines (107 loc) · 3.72 KB
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
"""This module contains the quick sort method (quick_srt), which performs an
in-place sort on a passed in list. Quick sort has a best case time
complexity of O(n log n) when all elements are equal, and a worst case of
O(n2). Quick sort is not stable or adaptive, but it is robust and has low
overhead.
This module was completed with reference to:
Quicksort: A Python Implementation
http://pfsensesetup.com/pythonscript.net/quicksort-a-python-implementation/
by maximumdx
See the excellent 'sortingalgorithms.com' for more information.
"""
def quick_srt(un_list):
"""Sort a list in place with quick sort.
args:
un_list: the list to be sorted
"""
_quick_srt(un_list, low=0, high=-1)
def _quick_srt(un_list, low=0, high=-1):
"""Sort a list in place with quick sort.
args:
un_list: the list to be sorted
low: index lower bound
high: the index upper bound
"""
if high == -1:
high = len(un_list) - 1
if high > low:
pivot = _partition(un_list, low, high)
if pivot > 0:
_quick_srt(un_list, low, pivot-1)
if pivot > -1:
_quick_srt(un_list, pivot+1, high)
def _partition(un_list, low=0, high=-1):
"""Partition the list into values less than and greater than pivot.
If the the partitioned sublist contains at least two unique values,
the pivot index is returned. Else, a value of -1 is returned, which
will end any further recursive calls to _quick_srt.
args:
un_list: the list to be sorted
low: index lower bound
high: the index upper bound
returns: the pivot index or -1
"""
if high == -1:
high = len(un_list) - 1
pivot = _choose_pivot(un_list, low, high)
_swap(un_list, pivot, high)
j = low
for i in range(low, high+1):
if un_list[i] < un_list[high]:
_swap(un_list, i, j)
j += 1
_swap(un_list, high, j)
for i in range(low, high):
if un_list[i] != un_list[i+1]:
return j
return -1
def _swap(un_list, x, y):
"""Swap the values at two index positions in list.
args:
un_list: the list to act upon
x: index to first element
y: index to second element
"""
temp = un_list[x]
un_list[x] = un_list[y]
un_list[y] = temp
def _choose_pivot(un_list, low=0, high=-1):
"""Choose a pivot for quick sort.
args:
un_list: the list to be sorted
low: index lower bound
high: the index upper bound
returns: the pivot index
"""
if high == -1:
high = len(un_list) - 1
mid = low + (high - low) // 2
if un_list[low] == un_list[mid] and un_list[mid] == un_list[high]:
return mid
if (un_list[low] < un_list[mid]
and un_list[low] < un_list[high]
and un_list[mid] < un_list[high]):
return mid
elif (un_list[mid] < un_list[low]
and un_list[mid] < un_list[high]
and un_list[low] < un_list[high]):
return low
else:
return high
if __name__ == '__main__':
from random import randint
rands = [randint(1, 10001) for x in range(1, 10001)]
dupes = [1 for x in range(1, 10001)]
nums = range(0, 10001)
BEST_CASE = dupes
WORST_CASE = rands
from timeit import Timer
SETUP = """from __main__ import BEST_CASE, WORST_CASE, quick_srt"""
best = Timer('quick_srt({})'.format(BEST_CASE), SETUP).timeit(100)
worst = Timer('quick_srt({})'.format(WORST_CASE), SETUP).timeit(100)
print("""
Best case represented as a list that being a list of the same values.
Worst case represented as a list that is random numbers.
""")
print('Best Case: {}'.format(best))
print('Worst Case: {}'.format(worst))