-
-
Notifications
You must be signed in to change notification settings - Fork 50.8k
Expand file tree
/
Copy pathtournament_sort.py
More file actions
97 lines (84 loc) · 2.89 KB
/
Copy pathtournament_sort.py
File metadata and controls
97 lines (84 loc) · 2.89 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
"""
Tournament Sort algorithm implementation.
Tournament sort works by creating a tournament tree (a min-heap style
binary tree) where elements compete against each other. The smallest
element wins each round and is extracted, similar to a sports tournament.
Time Complexity:
Best Case: O(n log n)
Average Case: O(n log n)
Worst Case: O(n log n)
Space Complexity: O(n)
Reference: https://en.wikipedia.org/wiki/Tournament_sort
"""
def tournament_sort(sequence: list[int]) -> list[int]:
"""
Sort a list using the tournament sort algorithm.
:param sequence: list of integers to sort
:return: sorted list in ascending order
>>> tournament_sort([0, 5, 3, 1, 2])
[0, 1, 2, 3, 5]
>>> tournament_sort([])
[]
>>> tournament_sort([1])
[1]
>>> tournament_sort([5, 4, 3, 2, 1])
[1, 2, 3, 4, 5]
>>> tournament_sort([1, 1, 1])
[1, 1, 1]
>>> tournament_sort([-3, -1, -2])
[-3, -2, -1]
>>> tournament_sort([3, -1, 0, -5, 2])
[-5, -1, 0, 2, 3]
"""
if len(sequence) <= 1:
return list(sequence)
def build_tree(arr: list[int]) -> list[int | None]:
"""Build a tournament tree from the array."""
n = len(arr)
# Tree size: leaves start at index n (1-indexed internal nodes)
tree: list[int | None] = [None] * (2 * n)
# Fill leaves
for i in range(n):
tree[n + i] = arr[i]
# Build internal nodes (winners)
for i in range(n - 1, 0, -1):
left = tree[2 * i]
right = tree[2 * i + 1]
if left is None:
tree[i] = right
elif right is None:
tree[i] = left
else:
tree[i] = min(left, right)
return tree
def extract_min(tree: list[int | None], n: int) -> int:
"""Extract minimum value and remove it from tree."""
min_val = tree[1]
# Find the leaf holding min_val and remove it
i = 1
while i < n:
left = tree[2 * i]
right = tree[2 * i + 1]
i = 2 * i if left == min_val else 2 * i + 1
tree[i] = None
# Update internal nodes on path back to root
i //= 2
while i >= 1:
left = tree[2 * i]
right = tree[2 * i + 1]
if left is None:
tree[i] = right
elif right is None:
tree[i] = left
else:
tree[i] = min(left, right)
i //= 2
return min_val # type: ignore[return-value]
n = len(sequence)
tree = build_tree(sequence)
return [extract_min(tree, n) for _ in range(n)]
if __name__ == "__main__":
user_input = input("Enter numbers separated by comma:\n").strip()
sequence = [int(item.strip()) for item in user_input.split(",")]
sorted_sequence = tournament_sort(sequence)
print(f"tournament_sort({sequence}) = {sorted_sequence}")