algos/src/merge_sort.rs

49 lines
1.0 KiB
Rust

use std::clone::Clone;
use std::cmp::PartialOrd;
fn merge_count_inversions<T: Clone + PartialOrd + Copy + std::fmt::Debug>(
a: Vec<T>,
b: Vec<T>,
) -> (Vec<T>, usize) {
let mut r = vec![];
let mut i = 0;
let mut j = 0;
let mut inversions = 0;
while i < a.len() && j < b.len() {
if a[i] < b[j] {
r.push(a[i]);
i += 1;
} else {
r.push(b[j]);
j += 1;
inversions += a.len() - i;
}
}
while i < a.len() {
r.push(a[i]);
i += 1;
}
while j < b.len() {
r.push(b[j]);
j += 1;
}
return (r, inversions);
}
pub fn merge_sort_inversions<T: Clone + PartialOrd + Copy + std::fmt::Debug>(
v: Vec<T>,
) -> (Vec<T>, usize) {
if v.len() <= 1 {
return (v, 0);
}
let i = v.len() / 2;
let (a, n) = merge_sort_inversions((&v[..i]).to_vec());
let (b, m) = merge_sort_inversions((&v[i..]).to_vec());
let (r, p) = merge_count_inversions(a, b);
return (r, n + m + p);
}