forked from alexfertel/rust-algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcounting_sort.rs
95 lines (80 loc) · 2.07 KB
/
counting_sort.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
pub fn counting_sort<T: Keyed + Ord + Copy + Default>(array: &[T]) -> Vec<T> {
let max: usize = array.iter().map(|item: &T| item.key()).max().unwrap_or(0);
let mut count: Vec<usize> = vec![0; max + 1];
let mut output: Vec<T> = vec![T::default(); array.len()];
for &element in array.iter() {
count[element.key()] += 1;
}
for i in 1..max + 1 {
count[i] += count[i - 1];
}
for i in (0..array.len()).rev() {
let j = array[i].key();
count[j] -= 1;
output[count[j]] = array[i];
}
output
}
pub trait Keyed {
fn key(&self) -> usize;
}
#[cfg(test)]
mod tests {
use super::counting_sort;
use super::Keyed;
sorting_tests!(counting_sort);
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Default)]
struct Custom {
key: usize,
}
impl Keyed for Custom {
fn key(&self) -> usize {
self.key
}
}
impl Keyed for usize {
fn key(&self) -> usize {
*self
}
}
#[test]
fn basic_struct() {
let array = [
Custom { key: 5 },
Custom { key: 4 },
Custom { key: 1 },
Custom { key: 6 },
Custom { key: 0 },
];
let output = counting_sort(&array);
assert_sorted!(&output);
}
#[test]
fn repeated_elements_struct() {
let array = [
Custom { key: 5 },
Custom { key: 5 },
Custom { key: 1 },
Custom { key: 6 },
Custom { key: 1 },
Custom { key: 0 },
Custom { key: 2 },
Custom { key: 6 },
];
let output = counting_sort(&array);
assert_sorted!(&output);
}
#[test]
fn pre_sorted_struct() {
let array = [
Custom { key: 1 },
Custom { key: 2 },
Custom { key: 3 },
Custom { key: 4 },
Custom { key: 5 },
Custom { key: 6 },
];
let output = counting_sort(&array);
assert_sorted!(&output);
}
}