Skip to content

Commit 7148661

Browse files
GziXnineDenizAltunkapanalxkm
authored
Feat/tournament sort (#7201)
* feat: implement Smooth Sort algorithm with detailed JavaDoc and test class * style: format LEONARDO array for improved readability with clang-format * feat(sorts): add TournamentSort (winner-tree) * test: add unit test for null array handling in TournamentSort --------- Co-authored-by: Ahmed Allam <[email protected]> Co-authored-by: Deniz Altunkapan <[email protected]> Co-authored-by: Oleksandr Klymenko <[email protected]>
1 parent bdda4fa commit 7148661

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.thealgorithms.sorts;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* Tournament Sort algorithm implementation.
7+
*
8+
* Tournament sort builds a winner tree (a complete binary tree storing the index
9+
* of the smallest element in each subtree). It then repeatedly extracts the
10+
* winner (minimum) and updates the path from the removed leaf to the root.
11+
*
12+
* Time Complexity:
13+
* - Best case: O(n log n)
14+
* - Average case: O(n log n)
15+
* - Worst case: O(n log n)
16+
*
17+
* Space Complexity: O(n) – additional winner-tree storage
18+
*
19+
* @see <a href="https://en.wikipedia.org/wiki/Tournament_sort">Tournament Sort Algorithm</a>
20+
* @see SortAlgorithm
21+
*/
22+
public class TournamentSort implements SortAlgorithm {
23+
24+
@Override
25+
public <T extends Comparable<T>> T[] sort(T[] array) {
26+
if (array == null || array.length < 2) {
27+
return array;
28+
}
29+
30+
final int n = array.length;
31+
final int leafCount = nextPowerOfTwo(n);
32+
33+
// Winner tree represented as an array:
34+
// - Leaves live at [leafCount .. 2*leafCount)
35+
// - Internal nodes live at [1 .. leafCount)
36+
// Each node stores an index into the original array or -1 for "empty".
37+
final int[] tree = new int[2 * leafCount];
38+
Arrays.fill(tree, -1);
39+
40+
for (int i = 0; i < n; i++) {
41+
tree[leafCount + i] = i;
42+
}
43+
44+
for (int node = leafCount - 1; node >= 1; node--) {
45+
tree[node] = winnerIndex(array, tree[node * 2], tree[node * 2 + 1]);
46+
}
47+
48+
final T[] result = array.clone();
49+
for (int out = 0; out < n; out++) {
50+
final int winner = tree[1];
51+
result[out] = array[winner];
52+
53+
int node = leafCount + winner;
54+
tree[node] = -1;
55+
56+
for (node /= 2; node >= 1; node /= 2) {
57+
tree[node] = winnerIndex(array, tree[node * 2], tree[node * 2 + 1]);
58+
}
59+
}
60+
61+
System.arraycopy(result, 0, array, 0, n);
62+
return array;
63+
}
64+
65+
private static int nextPowerOfTwo(int n) {
66+
int power = 1;
67+
while (power < n) {
68+
power <<= 1;
69+
}
70+
return power;
71+
}
72+
73+
private static <T extends Comparable<T>> int winnerIndex(T[] array, int leftIndex, int rightIndex) {
74+
if (leftIndex == -1) {
75+
return rightIndex;
76+
}
77+
if (rightIndex == -1) {
78+
return leftIndex;
79+
}
80+
81+
// If equal, prefer the left element to keep ordering deterministic.
82+
return SortUtils.less(array[rightIndex], array[leftIndex]) ? rightIndex : leftIndex;
83+
}
84+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.thealgorithms.sorts;
2+
3+
import static org.junit.jupiter.api.Assertions.assertNull;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class TournamentSortTest extends SortingAlgorithmTest {
8+
9+
@Test
10+
void shouldAcceptWhenNullArrayIsPassed() {
11+
Integer[] array = null;
12+
assertNull(getSortAlgorithm().sort(array));
13+
}
14+
15+
@Override
16+
SortAlgorithm getSortAlgorithm() {
17+
return new TournamentSort();
18+
}
19+
}

0 commit comments

Comments
 (0)