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))
}
}