pub fn sort(slice: &mut [u32]) {
if slice.len() <= 1 {
return;
}
let max = find_max(slice);
let mut exp = 1;
while max / exp > 0 {
counting_sort_by_digit(slice, exp);
exp *= 10;
}
}
fn counting_sort_by_digit(slice: &mut [u32], exp: u32) {
let len = slice.len();
let mut output = vec![0; len];
let mut count = [0; 10];
for &num in slice.iter() {
count[get_digit(num, exp)] += 1;
}
for i in 1..10 {
count[i] += count[i - 1];
}
for &num in slice.iter().rev() {
let digit = get_digit(num, exp);
count[digit] -= 1;
output[count[digit]] = num;
}
slice.copy_from_slice(&output);
}
fn get_digit(num: u32, exp: u32) -> usize {
((num / exp) % 10) as usize
}
fn find_max(slice: &[u32]) -> u32 {
slice.iter().max().copied().unwrap_or(0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty_slice() {
let mut arr: Vec<u32> = vec![];
sort(&mut arr);
assert_eq!(arr, Vec::<u32>::new());
}
#[test]
fn test_single_element() {
let mut arr = vec![1];
sort(&mut arr);
assert_eq!(arr, vec![1]);
}
#[test]
fn test_sorted_array() {
let mut arr = vec![1, 2, 3, 4, 5];
sort(&mut arr);
assert_eq!(arr, vec![1, 2, 3, 4, 5]);
}
#[test]
fn test_reverse_sorted() {
let mut arr = vec![5, 4, 3, 2, 1];
sort(&mut arr);
assert_eq!(arr, vec![1, 2, 3, 4, 5]);
}
#[test]
fn test_random_order() {
let mut arr = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
let mut expected = arr.clone();
expected.sort();
sort(&mut arr);
assert_eq!(arr, expected);
}
#[test]
fn test_duplicate_elements() {
let mut arr = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
let mut expected = arr.clone();
expected.sort();
sort(&mut arr);
assert_eq!(arr, expected);
}
#[test]
fn test_large_array() {
let mut arr: Vec<u32> = (0..1000).rev().collect();
let mut expected = arr.clone();
expected.sort();
sort(&mut arr);
assert_eq!(arr, expected);
}
#[test]
fn test_all_equal() {
let mut arr = vec![1, 1, 1, 1, 1];
sort(&mut arr);
assert_eq!(arr, vec![1, 1, 1, 1, 1]);
}
#[test]
fn test_stability() {
#[derive(Debug, Clone, PartialEq)]
struct Pair {
key: u32,
original_index: usize,
}
let pairs = vec![
Pair {
key: 501,
original_index: 0,
},
Pair {
key: 501,
original_index: 1,
},
Pair {
key: 502,
original_index: 2,
},
Pair {
key: 502,
original_index: 3,
},
];
let mut values: Vec<u32> = pairs.iter().map(|p| p.key).collect();
sort(&mut values);
for i in 0..pairs.len() - 1 {
for j in i + 1..pairs.len() {
if pairs[i].key == pairs[j].key {
let pos_i = values.iter().position(|&x| x == pairs[i].key).unwrap();
let pos_j = values.iter().rposition(|&x| x == pairs[j].key).unwrap();
assert!(
pos_i < pos_j,
"Stability violated for equal elements at original positions {} and {}",
pairs[i].original_index,
pairs[j].original_index
);
}
}
}
}
#[test]
fn test_zero_and_max() {
let mut arr = vec![0, 1000000, 5, 999999, 0];
sort(&mut arr);
assert_eq!(arr, vec![0, 0, 5, 999999, 1000000]);
}
#[test]
fn test_find_max() {
assert_eq!(find_max(&[1, 5, 3, 9, 2]), 9);
assert_eq!(find_max(&[1]), 1);
assert_eq!(find_max(&[1000000, 0, 5]), 1000000);
}
#[test]
fn test_get_digit() {
assert_eq!(get_digit(123, 1), 3); assert_eq!(get_digit(123, 10), 2); assert_eq!(get_digit(123, 100), 1); assert_eq!(get_digit(123, 1000), 0); }
#[test]
fn test_different_digit_lengths() {
let mut arr = vec![1, 10, 100, 1000, 10000];
sort(&mut arr);
assert_eq!(arr, vec![1, 10, 100, 1000, 10000]);
}
#[test]
fn test_power_of_ten() {
let mut arr = vec![1, 10, 100, 1000, 10000];
sort(&mut arr);
assert_eq!(arr, vec![1, 10, 100, 1000, 10000]);
}
#[test]
fn test_repeated_digits() {
let mut arr = vec![111, 222, 111, 222];
sort(&mut arr);
assert_eq!(arr, vec![111, 111, 222, 222]);
}
#[test]
fn test_single_digit_numbers() {
let mut arr = vec![9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
sort(&mut arr);
assert_eq!(arr, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
}