-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy path3.1. quicksort.py
104 lines (84 loc) · 3.03 KB
/
3.1. quicksort.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
# def quickSort(arr):
# if len(arr) <= 1:
# return arr
#
# def sort(array, pivot_idx, right_idx):
# left_idx = pivot_idx + 1
# while right_idx >= left_idx:
# pivot = array[pivot_idx]
# left = array[left_idx]
# right = array[right_idx]
#
# if left > pivot > right:
# swap(array, left_idx, right_idx)
# if left <= pivot:
# left_idx += 1
# if right >= pivot:
# right_idx -= 1
#
# # print(left_idx, right_idx, array)
# swap(array, pivot_idx, right_idx)
# # print(array)
# # now right idx is ok lets do the same for array[:right_idx] and array[right_idx + 1:]
# return quickSort(array[:right_idx]) + [array[right_idx]] + quickSort(array[right_idx + 1:])
#
# # print('------')
# return sort(arr, 0, len(arr) - 1)
def quickSort(arr):
sort_last_as_pivot(arr, 0, len(arr) - 1)
return arr
def sort_first_as_pivot(array, start_idx, end_idx): # sort using the first index as pivot
if start_idx >= end_idx:
return
pivot_idx = start_idx
left_idx = pivot_idx + 1
right_idx = end_idx
while right_idx >= left_idx:
pivot = array[pivot_idx]
left = array[left_idx]
right = array[right_idx]
if left > pivot > right:
swap(array, left_idx, right_idx)
if left <= pivot:
left_idx += 1
if right >= pivot:
right_idx -= 1
swap(array, pivot_idx, right_idx)
# print(pivot_idx, start_idx, left_idx, right_idx, end_idx)
left_smaller = right_idx - 1 - start_idx < end_idx - (right_idx + 1)
if left_smaller:
sort_first_as_pivot(array, start_idx, right_idx - 1)
sort_first_as_pivot(array, right_idx + 1, end_idx)
else:
sort_first_as_pivot(array, right_idx + 1, end_idx)
sort_first_as_pivot(array, start_idx, right_idx - 1)
def sort_last_as_pivot(array, start_idx, end_idx): # sort using the last index as pivot
if start_idx >= end_idx:
return
pivot_idx = end_idx
left_idx = start_idx
right_idx = pivot_idx - 1
while right_idx >= left_idx:
pivot = array[pivot_idx]
left = array[left_idx]
right = array[right_idx]
if left > pivot > right:
swap(array, left_idx, right_idx)
if left <= pivot:
left_idx += 1
if right >= pivot:
right_idx -= 1
swap(array, pivot_idx, left_idx)
# print(array)
left_smaller = right_idx - 1 - start_idx < end_idx - (right_idx + 1)
if left_smaller:
sort_last_as_pivot(array, start_idx, left_idx - 1)
sort_last_as_pivot(array, left_idx + 1, end_idx)
else:
sort_last_as_pivot(array, left_idx + 1, end_idx)
sort_last_as_pivot(array, start_idx, left_idx - 1)
def swap(array, i, j):
array[i], array[j] = array[j], array[i]
if __name__ == '__main__':
# print(quickSort([-2, 3, 2, 4, - 1, 1, 0, -1, 9, -10]))
print(quickSort([-1, 8, 5, 2, 9, 5, 6, 3]))