-
-
Notifications
You must be signed in to change notification settings - Fork 51.1k
Expand file tree
/
Copy pathbitonic_sort.py
More file actions
125 lines (98 loc) · 3.52 KB
/
Copy pathbitonic_sort.py
File metadata and controls
125 lines (98 loc) · 3.52 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
"""
Python program for Bitonic Sort.
Note that this program works only when size of input is a power of 2.
"""
from __future__ import annotations
from typing import Protocol
class Comparable(Protocol):
def __lt__(self, other: object, /) -> bool: ...
def comp_and_swap[T: Comparable](
array: list[T], index1: int, index2: int, direction: int
) -> None:
"""Compare the value at given index1 and index2 of the array and swap them as per
the given direction.
The parameter direction indicates the sorting direction, ASCENDING(1) or
DESCENDING(0); if (a[i] > a[j]) agrees with the direction, then a[i] and a[j] are
interchanged.
>>> arr = [12, 42, -21, 1]
>>> comp_and_swap(arr, 1, 2, 1)
>>> arr
[12, -21, 42, 1]
>>> comp_and_swap(arr, 1, 2, 0)
>>> arr
[12, 42, -21, 1]
>>> comp_and_swap(arr, 0, 3, 1)
>>> arr
[1, 42, -21, 12]
>>> comp_and_swap(arr, 0, 3, 0)
>>> arr
[12, 42, -21, 1]
"""
if (direction == 1 and array[index2] < array[index1]) or (
direction == 0 and array[index1] < array[index2]
):
array[index1], array[index2] = array[index2], array[index1]
def bitonic_merge[T: Comparable](
array: list[T], low: int, length: int, direction: int
) -> None:
"""
It recursively sorts a bitonic sequence in ascending order, if direction = 1, and in
descending if direction = 0.
The sequence to be sorted starts at index position low, the parameter length is the
number of elements to be sorted.
>>> arr = [12, 42, -21, 1]
>>> bitonic_merge(arr, 0, 4, 1)
>>> arr
[-21, 1, 12, 42]
>>> bitonic_merge(arr, 0, 4, 0)
>>> arr
[42, 12, 1, -21]
"""
if length > 1:
middle = int(length / 2)
for i in range(low, low + middle):
comp_and_swap(array, i, i + middle, direction)
bitonic_merge(array, low, middle, direction)
bitonic_merge(array, low + middle, middle, direction)
def bitonic_sort[T: Comparable](
array: list[T], low: int, length: int, direction: int
) -> None:
"""
This function first produces a bitonic sequence by recursively sorting its two
halves in opposite sorting orders, and then calls bitonic_merge to make them in the
same order.
>>> arr = [12, 34, 92, -23, 0, -121, -167, 145]
>>> bitonic_sort(arr, 0, 8, 1)
>>> arr
[-167, -121, -23, 0, 12, 34, 92, 145]
>>> bitonic_sort(arr, 0, 8, 0)
>>> arr
[145, 92, 34, 12, 0, -23, -121, -167]
>>> arr = ["banana", "apple", "cherry", "date"]
>>> bitonic_sort(arr, 0, 4, 1)
>>> arr
['apple', 'banana', 'cherry', 'date']
>>> arr = [3, 1.5, 2, 4.5]
>>> bitonic_sort(arr, 0, 4, 1)
>>> arr
[1.5, 2, 3, 4.5]
>>> arr = [1, "two", 3, "four"]
>>> bitonic_sort(arr, 0, 4, 1)
Traceback (most recent call last):
...
TypeError: '<' not supported between instances of 'str' and 'int'
"""
if length > 1:
middle = int(length / 2)
bitonic_sort(array, low, middle, 1)
bitonic_sort(array, low + middle, middle, 0)
bitonic_merge(array, low, length, direction)
if __name__ == "__main__":
user_input = input("Enter numbers separated by a comma:\n").strip()
unsorted = [int(item.strip()) for item in user_input.split(",")]
bitonic_sort(unsorted, 0, len(unsorted), 1)
print("\nSorted array in ascending order is: ", end="")
print(*unsorted, sep=", ")
bitonic_merge(unsorted, 0, len(unsorted), 0)
print("Sorted array in descending order is: ", end="")
print(*unsorted, sep=", ")