Skip to content

Commit 8ba3163

Browse files
authored
Added tournament sort algorithm (#1046)
1 parent fa0aa80 commit 8ba3163

3 files changed

Lines changed: 119 additions & 0 deletions

File tree

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@
390390
* [Stooge Sort](https://github.com/TheAlgorithms/Rust/blob/master/src/sorting/stooge_sort.rs)
391391
* [Strand Sort](https://github.com/TheAlgorithms/Rust/blob/master/src/sorting/strand_sort.rs)
392392
* [Tim Sort](https://github.com/TheAlgorithms/Rust/blob/master/src/sorting/tim_sort.rs)
393+
* [Tournament Sort](https://github.com/TheAlgorithms/Rust/blob/master/src/sorting/tournament_sort.rs)
393394
* [Tree Sort](https://github.com/TheAlgorithms/Rust/blob/master/src/sorting/tree_sort.rs)
394395
* [Wave Sort](https://github.com/TheAlgorithms/Rust/blob/master/src/sorting/wave_sort.rs)
395396
* [Wiggle Sort](https://github.com/TheAlgorithms/Rust/blob/master/src/sorting/wiggle_sort.rs)

src/sorting/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mod sort_utils;
3030
mod stooge_sort;
3131
mod strand_sort;
3232
mod tim_sort;
33+
mod tournament_sort;
3334
mod tree_sort;
3435
mod wave_sort;
3536
mod wiggle_sort;
@@ -67,6 +68,7 @@ pub use self::sleep_sort::sleep_sort;
6768
pub use self::stooge_sort::stooge_sort;
6869
pub use self::strand_sort::strand_sort;
6970
pub use self::tim_sort::tim_sort;
71+
pub use self::tournament_sort::tournament_sort;
7072
pub use self::tree_sort::tree_sort;
7173
pub use self::wave_sort::wave_sort;
7274
pub use self::wiggle_sort::wiggle_sort;

src/sorting/tournament_sort.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/// From Wikipedia:
2+
/// Tournament sort is a sorting algorithm. It improves upon the naive
3+
/// selection sort by using a priority queue to find the next element in
4+
/// the sort.
5+
///
6+
/// Time complexity is `O(n log n)`, where `n` is the number of elements.
7+
/// Space complexity is `O(n)`.
8+
pub fn tournament_sort<T>(arr: &[T]) -> Vec<T>
9+
where
10+
T: Ord + Clone,
11+
{
12+
let mut arr = arr.to_vec();
13+
let n = arr.len();
14+
let mut tree_size = 1;
15+
16+
while tree_size < n {
17+
tree_size <<= 1;
18+
}
19+
20+
let mut tree: Vec<Option<T>> = vec![None; 2 * tree_size];
21+
22+
for i in 0..tree_size {
23+
if i < n {
24+
tree[tree_size + i] = Some(arr[i].clone());
25+
} else {
26+
tree[tree_size + i] = None;
27+
}
28+
}
29+
30+
for i in (1..tree_size).rev() {
31+
tree[i] = min_opt(&tree[2 * i], &tree[2 * i + 1]);
32+
}
33+
34+
for i in 0..n {
35+
let min = tree[1].as_ref().unwrap().clone();
36+
arr[i] = min;
37+
let min_ref = &arr[i];
38+
39+
let mut pos = 1;
40+
while pos < tree_size {
41+
if tree[2 * pos].as_ref() == Some(min_ref) {
42+
pos *= 2;
43+
} else {
44+
pos = 2 * pos + 1;
45+
}
46+
}
47+
48+
tree[pos] = None;
49+
while pos > 1 {
50+
pos >>= 1;
51+
tree[pos] = min_opt(&tree[2 * pos], &tree[2 * pos + 1]);
52+
}
53+
}
54+
arr
55+
}
56+
57+
fn min_opt<T>(a: &Option<T>, b: &Option<T>) -> Option<T>
58+
where
59+
T: Ord + Clone,
60+
{
61+
match (a, b) {
62+
(Some(x), Some(y)) => Some(if x <= y { x.clone() } else { y.clone() }),
63+
(Some(x), None) => Some(x.clone()),
64+
(None, Some(y)) => Some(y.clone()),
65+
(None, None) => None,
66+
}
67+
}
68+
69+
#[cfg(test)]
70+
mod test {
71+
use super::*;
72+
use crate::sorting::have_same_elements;
73+
use crate::sorting::is_sorted;
74+
75+
#[test]
76+
fn descending() {
77+
let arr = vec![6, 5, 4, 3, 2, 1];
78+
let res = tournament_sort(&arr);
79+
assert!(is_sorted(&res) && have_same_elements(&res, &arr));
80+
}
81+
82+
#[test]
83+
fn empty() {
84+
let arr = Vec::<i32>::new();
85+
let res = tournament_sort(&arr);
86+
assert!(is_sorted(&res) && have_same_elements(&res, &arr));
87+
}
88+
89+
#[test]
90+
fn negative_numbers() {
91+
let arr = vec![-32, -54, -65, -12, -7];
92+
let res = tournament_sort(&arr);
93+
assert!(is_sorted(&res) && have_same_elements(&res, &arr));
94+
}
95+
96+
#[test]
97+
fn one_element() {
98+
let arr = vec![1];
99+
let res = tournament_sort(&arr);
100+
assert!(is_sorted(&res) && have_same_elements(&res, &arr));
101+
}
102+
103+
#[test]
104+
fn pre_sorted() {
105+
let arr = vec![5, 12, 23, 54, 57, 60];
106+
let res = tournament_sort(&arr);
107+
assert!(is_sorted(&res) && have_same_elements(&res, &arr));
108+
}
109+
110+
#[test]
111+
fn repeated_elements() {
112+
let arr = vec![42, 42, 42, 42];
113+
let res = tournament_sort(&arr);
114+
assert_eq!(&res, &arr);
115+
}
116+
}

0 commit comments

Comments
 (0)