|
| 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 | +} |
0 commit comments