algos/src/quick_sort.rs

67 lines
1.5 KiB
Rust

use std::cmp::PartialOrd;
fn median_of_three<T: PartialOrd + Copy>(v: &[T]) -> usize {
if v.len() < 3 {
return 0;
}
let left = 0;
let middle = if v.len() % 2 == 0 {
v.len() / 2 - 1
} else {
v.len() / 2
};
let right = v.len() - 1;
let mut values = vec![v[left], v[middle], v[right]];
bubble_sort(&mut values);
let median = values[1];
if median == v[left] {
return left;
} else if median == v[middle] {
return middle;
} else if median == v[right] {
return right;
} else {
panic!("Did not find median in values!");
}
}
fn bubble_sort<T: PartialOrd>(v: &mut [T]) -> () {
let mut unsorted = true;
if v.len() <= 1 {
return;
}
while unsorted {
unsorted = false;
for i in 0..v.len() - 1 {
if v[i] > v[i + 1] {
v.swap(i, i + 1);
unsorted = true;
}
}
}
}
pub fn quick_sort<T: PartialOrd + Copy>(v: &mut [T], comp_acc: &mut usize) -> () {
if v.len() <= 1 {
return;
}
// let pivot_index = 0;
// let pivot_index = v.len() - 1;
let pivot_index = median_of_three(&v);
let mut i = 1;
v.swap(0, pivot_index);
for j in 1..v.len() {
if v[j] < v[0] {
v.swap(i, j);
i += 1;
}
}
v.swap(0, i - 1);
quick_sort(&mut v[..i - 1], comp_acc);
quick_sort(&mut v[i..], comp_acc);
*comp_acc += v[..i - 1].len();
*comp_acc += v[i..].len();
}