Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions sort/tournament_sort.go
Original file line number Diff line number Diff line change
@@ -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
}
31 changes: 31 additions & 0 deletions sort/tournament_sort_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
}