forked from TheAlgorithms/Rust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
counting_sort.rs
93 lines (75 loc) · 2.53 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
/// In place counting sort for collections of u32
/// O(n + maxval) in time, where maxval is the biggest value an input can possibly take
/// O(maxval) in memory
/// u32 is chosen arbitrarly, a counting sort probably should'nt be used on data that requires bigger types.
pub fn counting_sort(arr: &mut [u32], maxval: usize) {
let mut occurences: Vec<usize> = vec![0; maxval + 1];
for &data in arr.iter() {
occurences[data as usize] += 1;
}
let mut i = 0;
for (data, &number) in occurences.iter().enumerate() {
for _ in 0..number {
arr[i] = data as u32;
i += 1;
}
}
}
use std::ops::AddAssign;
/// Generic implementation of a counting sort for all usigned types
pub fn generic_counting_sort<T: Into<u64> + From<u8> + AddAssign + Copy>(
arr: &mut [T],
maxval: usize,
) {
let mut occurences: Vec<usize> = vec![0; maxval + 1];
for &data in arr.iter() {
occurences[data.into() as usize] += 1;
}
// Current index in output array
let mut i = 0;
// current data point, necessary to be type-safe
let mut data = T::from(0);
// This will iterate from 0 to the largest data point in `arr`
// `number` contains the occurances of the data point `data`
for &number in occurences.iter() {
for _ in 0..number {
arr[i] = data;
i += 1;
}
data += T::from(1);
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::sorting::have_same_elements;
use crate::sorting::is_sorted;
#[test]
fn counting_sort_descending() {
let mut ve1 = vec![6, 5, 4, 3, 2, 1];
let cloned = ve1.clone();
counting_sort(&mut ve1, 6);
assert!(is_sorted(&ve1) && have_same_elements(&ve1, &cloned));
}
#[test]
fn counting_sort_pre_sorted() {
let mut ve2 = vec![1, 2, 3, 4, 5, 6];
let cloned = ve2.clone();
counting_sort(&mut ve2, 6);
assert!(is_sorted(&ve2) && have_same_elements(&ve2, &cloned));
}
#[test]
fn generic_counting_sort() {
let mut ve1: Vec<u8> = vec![100, 30, 60, 10, 20, 120, 1];
let cloned = ve1.clone();
super::generic_counting_sort(&mut ve1, 120);
assert!(is_sorted(&ve1) && have_same_elements(&ve1, &cloned));
}
#[test]
fn presorted_u64_counting_sort() {
let mut ve2: Vec<u64> = vec![1, 2, 3, 4, 5, 6];
let cloned = ve2.clone();
super::generic_counting_sort(&mut ve2, 6);
assert!(is_sorted(&ve2) && have_same_elements(&ve2, &cloned));
}
}