pub trait SortingAlgorithm {
fn sort<T: Ord>(&self, slice: &mut [T]);
}
pub struct PDQsort;
impl SortingAlgorithm for PDQsort {
fn sort<T: Ord>(&self, slice: &mut [T]) {
slice.sort_unstable();
}
}
pub struct Timsort;
impl SortingAlgorithm for Timsort {
fn sort<T: Ord>(&self, slice: &mut [T]) {
slice.sort();
}
}
pub struct InsertionSort;
impl SortingAlgorithm for InsertionSort {
fn sort<T: Ord>(&self, slice: &mut [T]) {
for i in 1..slice.len() {
let mut j = i;
while j > 0 && slice[j - 1] > slice[j] {
slice.swap(j - 1, j);
j -= 1;
}
}
}
}
pub fn sort<T: Ord, A: SortingAlgorithm>(slice: &mut [T], algo: &A) {
algo.sort(slice);
}
pub fn is_sorted<T: PartialOrd>(slice: &[T]) -> bool {
for i in 1..slice.len() {
if let Some(std::cmp::Ordering::Greater) | None = slice[i - 1].partial_cmp(&slice[i]) {
return false;
}
}
true
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn timsort() {
let mut v = [1, 2, 3, 6, 3, 1, 3, -4, 6, -2, 3, 0, 5, 3, 0, 12];
Timsort.sort(&mut v);
assert!(is_sorted(&v));
}
#[test]
fn pdqsort() {
let mut v = [1, 2, 3, 6, 3, 1, 3, -4, 6, -2, 3, 0, 5, 3, 0, 12];
PDQsort.sort(&mut v);
assert!(is_sorted(&v));
}
#[test]
fn insertion_sort() {
let mut v = [1, 2, 3, 6, 3, 1, 3, -4, 6, -2, 3, 0, 5, 3, 0, 12];
InsertionSort.sort(&mut v);
assert!(is_sorted(&v));
}
#[test]
fn it_sorts() {
let mut v = [1, 2, 3, 6, 3, 1, 3, -4, 6, -2, 3, 0, 5, 3, 0, 12];
sort(&mut v, &Timsort);
assert!(is_sorted(&v));
}
}