希尔排序

  1. pub fn shell_sort<T: Ord + Copy>(values: &mut Vec<T>) {
  2. // shell sort works by swiping the value at a given gap and decreasing the gap to 1
  3. fn insertion<T: Ord + Copy>(values: &mut Vec<T>, start: usize, gap: usize) {
  4. for i in ((start + gap)..values.len()).step_by(gap) {
  5. let val_current = values[i];
  6. let mut pos = i;
  7. // make swaps
  8. while pos >= gap && values[pos - gap] > val_current {
  9. values[pos] = values[pos - gap];
  10. pos -= gap;
  11. }
  12. values[pos] = val_current;
  13. }
  14. }
  15. let mut count_sublist = values.len() / 2; // makes gap as long as half of the array
  16. while count_sublist > 0 {
  17. for pos_start in 0..count_sublist {
  18. insertion(values, pos_start, count_sublist);
  19. }
  20. count_sublist /= 2; // makes gap as half of previous
  21. }
  22. }
  23. #[cfg(test)]
  24. mod test {
  25. use super::shell_sort;
  26. #[test]
  27. fn basic() {
  28. let mut vec = vec![3, 5, 6, 3, 1, 4];
  29. shell_sort(&mut vec);
  30. for i in 0..vec.len() - 1 {
  31. assert!(vec[i] <= vec[i + 1]);
  32. }
  33. }
  34. #[test]
  35. fn empty() {
  36. let mut vec: Vec<i32> = vec![];
  37. shell_sort(&mut vec);
  38. assert_eq!(vec, vec![]);
  39. }
  40. #[test]
  41. fn reverse() {
  42. let mut vec = vec![6, 5, 4, 3, 2, 1];
  43. shell_sort(&mut vec);
  44. for i in 0..vec.len() - 1 {
  45. assert!(vec[i] <= vec[i + 1]);
  46. }
  47. }
  48. #[test]
  49. fn already_sorted() {
  50. let mut vec = vec![1, 2, 3, 4, 5, 6];
  51. shell_sort(&mut vec);
  52. for i in 0..vec.len() - 1 {
  53. assert!(vec[i] <= vec[i + 1]);
  54. }
  55. }
  56. }