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
62 changes: 62 additions & 0 deletions Sorts/TournamentSort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Tournament Sort
*
* Tournament Sort improves upon naive Selection Sort by using a min-heap
* (priority queue) to find the minimum element in O(log n) instead of O(n),
* giving an overall time complexity of O(n log n).
*
* The name comes from its resemblance to a single-elimination sports tournament
* where the winner (minimum element) is found each round.
*
* Reference: https://en.wikipedia.org/wiki/Tournament_sort
*/

/**
* Restores the min-heap property by sifting down from index i.
* @param {number[]} heap - The heap array
* @param {number} n - Size of the heap
* @param {number} i - Index to sift down from
*/
const heapify = (heap, n, i) => {
let smallest = i
const left = 2 * i + 1
const right = 2 * i + 2

if (left < n && heap[left] < heap[smallest]) smallest = left
if (right < n && heap[right] < heap[smallest]) smallest = right

if (smallest !== i) {
;[heap[i], heap[smallest]] = [heap[smallest], heap[i]]
heapify(heap, n, smallest)
}
}

/**
* Sorts an array using Tournament Sort.
* @param {number[]} arr - The array to sort
* @returns {number[]} The sorted array
*/
const tournamentSort = (arr) => {
if (arr.length <= 1) return arr

const heap = [...arr]
const result = []

// Build min-heap
for (let i = Math.floor(heap.length / 2) - 1; i >= 0; i--) {
heapify(heap, heap.length, i)
}

// Extract minimum elements one by one
let size = heap.length
while (size > 0) {
result.push(heap[0])
heap[0] = heap[size - 1]
size--
heapify(heap, size, 0)
}

return result
}

export { tournamentSort }
31 changes: 31 additions & 0 deletions Sorts/TournamentSort.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { tournamentSort } from './TournamentSort.js'

describe('Tournament Sort', () => {
it('should sort an unsorted array', () => {
expect(tournamentSort([5, 3, 1, 4, 2])).toEqual([1, 2, 3, 4, 5])
})

it('should handle an already sorted array', () => {
expect(tournamentSort([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5])
})

it('should handle a reverse sorted array', () => {
expect(tournamentSort([5, 4, 3, 2, 1])).toEqual([1, 2, 3, 4, 5])
})

it('should handle a single element array', () => {
expect(tournamentSort([42])).toEqual([42])
})

it('should handle an empty array', () => {
expect(tournamentSort([])).toEqual([])
})

it('should handle duplicates', () => {
expect(tournamentSort([3, 1, 2, 1, 3])).toEqual([1, 1, 2, 3, 3])
})

it('should handle negative numbers', () => {
expect(tournamentSort([-3, 0, -1, 5, 2])).toEqual([-3, -1, 0, 2, 5])
})
})
Loading