计数排序

  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. pub fn counting_sort(arr: &mut [u32], maxval: usize) {
  6. let mut occurences: Vec<usize> = vec![0; maxval + 1];
  7. for &data in arr.iter() {
  8. occurences[data as usize] += 1;
  9. }
  10. let mut i = 0;
  11. for (data, &number) in occurences.iter().enumerate() {
  12. for _ in 0..number {
  13. arr[i] = data as u32;
  14. i += 1;
  15. }
  16. }
  17. }
  18. use std::ops::AddAssign;
  19. /// Generic implementation of a counting sort for all usigned types
  20. pub fn generic_counting_sort<T: Into<u64> + From<u8> + AddAssign + Copy>(
  21. arr: &mut [T],
  22. maxval: usize,
  23. ) {
  24. let mut occurences: Vec<usize> = vec![0; maxval + 1];
  25. for &data in arr.iter() {
  26. occurences[data.into() as usize] += 1;
  27. }
  28. // Current index in output array
  29. let mut i = 0;
  30. // current data point, necessary to be type-safe
  31. let mut data = T::from(0);
  32. // This will iterate from 0 to the largest data point in `arr`
  33. // `number` contains the occurances of the data point `data`
  34. for &number in occurences.iter() {
  35. for _ in 0..number {
  36. arr[i] = data;
  37. i += 1;
  38. }
  39. data += T::from(1);
  40. }
  41. }
  42. #[cfg(test)]
  43. mod test {
  44. use super::super::is_sorted;
  45. use super::*;
  46. #[test]
  47. fn counting_sort_descending() {
  48. let mut ve1 = vec![6, 5, 4, 3, 2, 1];
  49. counting_sort(&mut ve1, 6);
  50. assert!(is_sorted(&ve1));
  51. }
  52. #[test]
  53. fn counting_sort_pre_sorted() {
  54. let mut ve2 = vec![1, 2, 3, 4, 5, 6];
  55. counting_sort(&mut ve2, 6);
  56. assert!(is_sorted(&ve2));
  57. }
  58. #[test]
  59. fn generic_counting_sort() {
  60. let mut ve1: Vec<u8> = vec![100, 30, 60, 10, 20, 120, 1];
  61. super::generic_counting_sort(&mut ve1, 120);
  62. assert!(is_sorted(&ve1));
  63. }
  64. #[test]
  65. fn presorted_u64_counting_sort() {
  66. let mut ve2: Vec<u64> = vec![1, 2, 3, 4, 5, 6];
  67. super::generic_counting_sort(&mut ve2, 6);
  68. assert!(is_sorted(&ve2));
  69. }
  70. }