From 45219c11fbcdbaa4c70c8e7e9412556673b71442 Mon Sep 17 00:00:00 2001 From: Anmol Singh Date: Thu, 16 Oct 2025 03:35:16 -0400 Subject: [PATCH] feat(sorts): add TournamentSort (winner-tree) [#6631] --- .../thealgorithms/sorts/TournamentSort.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/main/java/com/thealgorithms/sorts/TournamentSort.java diff --git a/src/main/java/com/thealgorithms/sorts/TournamentSort.java b/src/main/java/com/thealgorithms/sorts/TournamentSort.java new file mode 100644 index 000000000000..67b866bcd2a9 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/TournamentSort.java @@ -0,0 +1,77 @@ +package com.thealgorithms.sorts; +import java.util.Arrays; + +/** + * Tournament Sort (Winner Tree) – comparison-based sorting that repeatedly + * selects the minimum via a "winner tree" and removes it, + * updating winners along the path. + * + * Time: O(n log m) where m is next power-of-two ≥ n + */ +public final class TournamentSort { + + private TournamentSort() { + } + + public static > void sort(T[] a) { + if (a == null || a.length < 2) return; + + final int n = a.length; + int m = 1; + while (m < n) m <<= 1; + + // Winner-tree nodes; + Node[] tree = new Node[2 * m]; + + for (int i = 0; i < n; i++) { + int leafPos = m + i; + tree[leafPos] = new Node<>(a[i], leafPos); + } + + for (int i = m - 1; i >= 1; i--) { + tree[i] = minNode(tree[2 * i], tree[2 * i + 1]); + } + + T[] out = Arrays.copyOf(a, n); + for (int k = 0; k < n; k++) { + Node winner = tree[1]; + out[k] = winner.value; + + // remove winner leaf by setting it to null (acts like +∞) + int pos = winner.leafPos; + tree[pos] = null; + + // re-compute winners up the path + pos >>= 1; + while (pos >= 1) { + tree[pos] = minNode(tree[2 * pos], tree[2 * pos + 1]); + pos >>= 1; + } + } + + System.arraycopy(out, 0, a, 0, n); + } + + public static void sort(int[] a) { + if (a == null || a.length < 2) return; + Integer[] boxed = new Integer[a.length]; + for (int i = 0; i < a.length; i++) boxed[i] = a[i]; + sort(boxed); + for (int i = 0; i < a.length; i++) a[i] = boxed[i]; + } + + private static > Node minNode(Node left, Node right) { + if (left == null) return right; + if (right == null) return left; + return (left.value.compareTo(right.value) <= 0) ? left : right; + } + + private static final class Node> { + final T value; + final int leafPos; + Node(T v, int p) { + this.value = v; + this.leafPos = p; + } + } +}