ndsort-rs 0.1.16

Sorting Algorithms implemented in Rust
Documentation
pub mod sorting {
    pub fn bubble_sort<T: PartialOrd>(arr: &mut [T]) {
        let mut swapped = true;
        let mut end = arr.len() - 1;

        while swapped {
            swapped = false;
            for i in 0..end {
                if arr[i] > arr[i + 1] {
                    arr.swap(i, i + 1);
                    swapped = true;
                }
            }
            end -= 1;
        }
    }

    pub fn shell_sort<T: PartialOrd>(arr: &mut [T]) {
        let n = arr.len();
        let mut h = 1;
        while h < n / 3 {
            h = 3 * h + 1;
        }
        while h >= 1 {
            for i in h..n {
                let mut j = i;
                while j >= h && arr[j] < arr[j - h] {
                    arr.swap(j, j - h);
                    j -= h;
                }
            }
            h /= 3;
        }
    }

    pub fn heap_sort<T: PartialOrd>(arr: &mut [T]) {
        let n = arr.len();

        for i in (0..n / 2).rev() {
            heapify(arr, n, i);
        }

        for i in (1..n).rev() {
            arr.swap(0, i);
            heapify(arr, i, 0);
        }
    }

    fn heapify<T: PartialOrd>(arr: &mut [T], n: usize, i: usize) {
        let mut largest = i;
        let left = 2 * i + 1;
        let right = 2 * i + 2;
        if left < n && arr[left] > arr[largest] {
            largest = left;
        }

        if right < n && arr[right] > arr[largest] {
            largest = right;
        }
        if largest != i {
            arr.swap(i, largest);
            heapify(arr, n, largest);
        }
    }

    pub fn quick_sort<T: PartialOrd + Copy>(arr: &mut [T]) {
        let len = arr.len();
        if len > 1 {
            let pivot = partition(arr);
            quick_sort(&mut arr[0..pivot]);
            quick_sort(&mut arr[pivot + 1..len]);
        }
    }

    fn partition<T: PartialOrd + Copy>(arr: &mut [T]) -> usize {
        let len = arr.len();
        let pivot_index = len / 2;
        let last_index = len - 1;

        arr.swap(pivot_index, last_index);
        let mut store_index = 0;
        for i in 0..last_index {
            if arr[i] < arr[last_index] {
                arr.swap(i, store_index);
                store_index += 1;
            }
        }
        arr.swap(store_index, last_index);
        store_index
    }

    pub fn merge_sort<T: Ord + Copy>(arr: &mut [T]) {
        let len = arr.len();
        if len <= 1 {
            return;
        }
        let mid = len / 2;
        merge_sort(&mut arr[..mid]);
        merge_sort(&mut arr[mid..]);
        let mut temp = Vec::with_capacity(len);
        let (mut i, mut j) = (0, mid);
        while i < mid && j < len {
            if arr[i] <= arr[j] {
                temp.push(arr[i]);
                i += 1;
            } else {
                temp.push(arr[j]);
                j += 1;
            }
        }
        temp.extend_from_slice(&arr[i..mid]);
        temp.extend_from_slice(&arr[j..]);
        arr.copy_from_slice(&temp);
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::sorting::*;
    use rand::Rng;

    #[test]
    fn test_bubble_sort() {
        let mut rng = rand::thread_rng();
        let arr = [0; 10000];
        let mut arr = arr.map(|_| rng.gen_range(0..1000));
        assert_eq!(arr.sort(), bubble_sort(&mut arr))
    }

    #[test]
    fn test_shell_sort() {
        let mut rng = rand::thread_rng();
        let arr = [0; 10000];
        let mut arr = arr.map(|_| rng.gen_range(0..1000));
        assert_eq!(arr.sort(), shell_sort(&mut arr))
    }

    #[test]
    fn test_heap_sort() {
        let mut rng = rand::thread_rng();
        let arr = [0; 10000];
        let mut arr = arr.map(|_| rng.gen_range(0..1000));
        let mut lettere = ['b', 'a', 'c'];
        assert_eq!(arr.sort(), heap_sort(&mut arr));
        assert_eq!(lettere.sort(), heap_sort(&mut lettere))
    }
}