From 14ff40eeee7ebffe605e7d6a500e8155053ee5f4 Mon Sep 17 00:00:00 2001 From: DANIEL DRORI Date: Tue, 2 Jun 2026 13:35:40 +0300 Subject: [PATCH] Add Tournament Sort implementation --- sort/tournament_sort.go | 51 ++++++++++++++++++++++++++++++++++++ sort/tournament_sort_test.go | 31 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 sort/tournament_sort.go create mode 100644 sort/tournament_sort_test.go diff --git a/sort/tournament_sort.go b/sort/tournament_sort.go new file mode 100644 index 000000000..d06d884b5 --- /dev/null +++ b/sort/tournament_sort.go @@ -0,0 +1,51 @@ +// tournament_sort.go +// Package sort provides Tournament Sort implementation. +// +// Tournament Sort improves upon naive Selection Sort by using a min-heap +// to find the minimum element in O(log n) instead of O(n), +// giving an overall time complexity of O(n log n). +// +// Reference: https://en.wikipedia.org/wiki/Tournament_sort + +package sort + +import "container/heap" + +// intHeap implements heap.Interface for a min-heap of ints. +type intHeap []int + +func (h intHeap) Len() int { return len(h) } +func (h intHeap) Less(i, j int) bool { return h[i] < h[j] } +func (h intHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h *intHeap) Push(x interface{}) { + *h = append(*h, x.(int)) +} + +func (h *intHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[:n-1] + return x +} + +// Tournament sorts a slice of integers using Tournament Sort. +// Time complexity: O(n log n), Space complexity: O(n) +func Tournament(arr []int) []int { + if len(arr) <= 1 { + return arr + } + + h := &intHeap{} + heap.Init(h) + for _, v := range arr { + heap.Push(h, v) + } + + result := make([]int, len(arr)) + for i := range result { + result[i] = heap.Pop(h).(int) + } + return result +} diff --git a/sort/tournament_sort_test.go b/sort/tournament_sort_test.go new file mode 100644 index 000000000..9147c2223 --- /dev/null +++ b/sort/tournament_sort_test.go @@ -0,0 +1,31 @@ +package sort + +import ( + "reflect" + "testing" +) + +func TestTournament(t *testing.T) { + tests := []struct { + name string + input []int + expected []int + }{ + {"unsorted", []int{5, 3, 1, 4, 2}, []int{1, 2, 3, 4, 5}}, + {"already sorted", []int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}}, + {"reverse sorted", []int{5, 4, 3, 2, 1}, []int{1, 2, 3, 4, 5}}, + {"single element", []int{42}, []int{42}}, + {"empty", []int{}, []int{}}, + {"duplicates", []int{3, 1, 2, 1, 3}, []int{1, 1, 2, 3, 3}}, + {"negative numbers", []int{-3, 0, -1, 5, 2}, []int{-3, -1, 0, 2, 5}}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := Tournament(tt.input) + if !reflect.DeepEqual(result, tt.expected) { + t.Errorf("Tournament(%v) = %v, want %v", tt.input, result, tt.expected) + } + }) + } +}