49 lines
1.0 KiB
Rust
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);
|
||
|
}
|