use std::cmp;
use super::insertion_sort;
fn merge<T: PartialOrd + Copy>(a: &mut [T], aux: &mut [T], lo: usize, mid: usize, hi: usize) {
for k in lo .. hi + 1 {
aux[k] = a[k];
}
let (mut i, mut j) = (lo, mid+1);
for k in lo .. hi + 1 {
if i > mid {
a[k] = aux[j];
j += 1;
} else if j > hi {
a[k] = aux[i];
i += 1;
} else if aux[j] < aux[i] {
a[k] = aux[j];
j += 1;
} else {
a[k] = aux[i];
i += 1;
}
}
}
const CUTOFF: usize = 7;
fn sort<T: PartialOrd + Copy>(a: &mut [T], aux: &mut [T], lo: usize, hi: usize) {
if hi <= lo + CUTOFF - 1 {
insertion_sort(&mut a[lo .. hi+1]);
return;
}
let mid = lo + (hi - lo) / 2;
sort(a, aux, lo, mid);
sort(a, aux, mid+1, hi);
if !(a[mid+1] < a[mid]) {
return;
}
merge(a, aux, lo, mid, hi);
}
pub fn merge_sort<T: PartialOrd + Copy>(a: &mut [T]) {
let n = a.len();
if n <= 1 {
return;
}
let mut aux: Vec<T> = a.iter().map(|&v| v).collect();
sort(a, &mut aux, 0, n - 1);
}
pub fn merge_bu_sort<T: PartialOrd + Copy + ::std::fmt::Debug>(a: &mut [T]) {
let n = a.len();
let mut aux: Vec<T> = a.iter().map(|&v| v).collect();
let mut sz = 1;
loop {
if !(sz < n) { break }
let mut lo = 0;
loop {
if !(lo < n - sz) { break }
merge(a, &mut aux, lo, lo+sz-1, cmp::min(lo+sz+sz-1, n-1));
lo += sz + sz;
}
sz = sz + sz;
}
}