Skip to content

Commit 57fced6

Browse files
Emilien FugierAnshulMalik
authored andcommitted
Add counting sort (#24)
1 parent 3102ab3 commit 57fced6

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

src/sorting/counting_sort.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/// In place counting sort for collections of u32
2+
/// O(n + maxval) in time, where maxval is the biggest value an input can possibly take
3+
/// O(maxval) in memory
4+
/// u32 is chosen arbitrarly, a counting sort probably should'nt be used on data that requires bigger types.
5+
use std::fmt::Debug;
6+
pub fn counting_sort(arr: &mut [u32], maxval: usize) {
7+
let mut occurences: Vec<usize> = vec![0; maxval + 1];
8+
9+
for &data in arr.iter() {
10+
occurences[data as usize] += 1;
11+
}
12+
13+
let mut i = 0;
14+
for (data, &number) in occurences.iter().enumerate() {
15+
for _ in 0..number {
16+
arr[i] = data as u32;
17+
i += 1;
18+
}
19+
}
20+
}
21+
22+
use std::ops::AddAssign;
23+
/// Generic implementation of a counting sort for all usigned types
24+
pub fn generic_counting_sort<T: Into<u64> + From<u8> + AddAssign + Copy + Debug>(
25+
arr: &mut [T],
26+
maxval: usize,
27+
) {
28+
let mut occurences: Vec<usize> = vec![0; maxval + 1];
29+
30+
for &data in arr.iter() {
31+
occurences[data.into() as usize] += 1;
32+
}
33+
34+
// Current index in output array
35+
let mut i = 0;
36+
37+
// current data point, necessary to be type-safe
38+
let mut data = T::from(0);
39+
40+
// This will iterate from 0 to the largest data point in `arr`
41+
// `number` contains the occurances of the data point `data`
42+
for &number in occurences.iter() {
43+
for _ in 0..number {
44+
arr[i] = data;
45+
i += 1;
46+
}
47+
48+
data += T::from(1);
49+
}
50+
}
51+
52+
#[cfg(test)]
53+
mod test {
54+
#[test]
55+
fn counting_sort() {
56+
//descending
57+
let mut ve1 = vec![6, 5, 4, 3, 2, 1];
58+
super::counting_sort(&mut ve1, 6);
59+
for i in 0..ve1.len() - 1 {
60+
assert!(ve1[i] <= ve1[i + 1]);
61+
}
62+
63+
//pre-sorted
64+
let mut ve2 = vec![1, 2, 3, 4, 5, 6];
65+
super::counting_sort(&mut ve2, 6);
66+
for i in 0..ve2.len() - 1 {
67+
assert!(ve2[i] <= ve2[i + 1]);
68+
}
69+
}
70+
#[test]
71+
fn generic_counting_sort() {
72+
//descending u8
73+
let mut ve1: Vec<u8> = vec![100, 30, 60, 10, 20, 120, 1];
74+
super::generic_counting_sort(&mut ve1, 120);
75+
println!("{:?}", ve1);
76+
for i in 0..ve1.len() - 1 {
77+
assert!(ve1[i] <= ve1[i + 1]);
78+
}
79+
80+
//pre-sorted u64
81+
let mut ve2: Vec<u64> = vec![1, 2, 3, 4, 5, 6];
82+
super::generic_counting_sort(&mut ve2, 6);
83+
for i in 0..ve2.len() - 1 {
84+
assert!(ve2[i] <= ve2[i + 1]);
85+
}
86+
}
87+
}

src/sorting/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
mod bubble_sort;
2+
mod counting_sort;
23
mod insertion;
34
mod quick_sort;
45

56
pub use self::bubble_sort::bubble_sort;
7+
pub use self::counting_sort::counting_sort;
8+
pub use self::counting_sort::generic_counting_sort;
69
pub use self::insertion::insertion_sort;
710
pub use self::quick_sort::quick_sort;

0 commit comments

Comments
 (0)