use std::time::{ Instant, Duration };
pub trait MergeSort<T: PartialEq + PartialOrd + Clone + Copy> {
fn merge_sort(&mut self);
fn merge_sort_timed(&mut self) -> Duration;
fn merge_sort_stepped(&mut self) -> Vec<Vec<T>>;
fn merge_sort_stepped_and_timed(&mut self) -> (Vec<Vec<T>>, Duration);
}
impl<T> MergeSort<T> for Vec<T>
where T: PartialEq + PartialOrd + Clone + Copy,
{
fn merge_sort(&mut self) {
if self.len() <= 1 {
return;
}
let rhs = &self[..self.len()/2];
let lhs = &self[self.len()/2..];
*self = merge_rec(rhs.to_vec(), lhs.to_vec());
}
fn merge_sort_timed(&mut self) -> Duration {
let time = Instant::now();
if self.len() <= 1 {
return time.elapsed();
}
let rhs = &self[..self.len()/2];
let lhs = &self[self.len()/2..];
*self = merge_rec(rhs.to_vec(), lhs.to_vec());
return time.elapsed();
}
fn merge_sort_stepped(&mut self) -> Vec<Vec<T>> {
let mut steps = vec![self.clone()];
if self.len() <= 1 {
return steps;
}
let rhs = &self[..self.len()/2];
let lhs = &self[self.len()/2..];
*self = merge_rec_stepped(rhs.to_vec(), lhs.to_vec(), &mut steps);
return steps;
}
fn merge_sort_stepped_and_timed(&mut self) -> (Vec<Vec<T>>, Duration) {
let time = Instant::now();
let mut steps = vec![self.clone()];
if self.len() <= 1 {
return (steps, time.elapsed());
}
let rhs = &self[..self.len()/2];
let lhs = &self[self.len()/2..];
*self = merge_rec_stepped(rhs.to_vec(), lhs.to_vec(), &mut steps);
(steps, time.elapsed())
}
}
pub fn merge_sort<T>(arr: Vec<T>) -> Vec<T>
where T: PartialEq + PartialOrd + Clone + Copy,
{
if arr.len() <= 1 {
return arr;
}
let rhs = &arr[..arr.len()/2];
let lhs = &arr[arr.len()/2..];
merge_rec(rhs.to_vec(), lhs.to_vec())
}
pub fn merge_sort_timed<T>(arr: Vec<T>) -> (Vec<T>, Duration)
where T: PartialEq + PartialOrd + Clone + Copy,
{
let time = Instant::now();
if arr.len() <= 1 {
return (arr, time.elapsed());
}
let rhs = &arr[..arr.len()/2];
let lhs = &arr[arr.len()/2..];
(merge_rec(rhs.to_vec(), lhs.to_vec()), time.elapsed())
}
pub fn merge_sort_stepped<T>(arr: Vec<T>) -> (Vec<T>, Vec<Vec<T>>)
where T: PartialEq + PartialOrd + Clone + Copy,
{
let mut steps = vec![arr.clone()];
if arr.len() <= 1 {
return (arr, steps);
}
let rhs = &arr[..arr.len()/2];
let lhs = &arr[arr.len()/2..];
let sorted = merge_rec_stepped(rhs.to_vec(), lhs.to_vec(), &mut steps);
(sorted, steps)
}
pub fn merge_sort_stepped_and_timed<T>(arr: Vec<T>) -> (Vec<T>, Vec<Vec<T>>, Duration)
where T: PartialEq + PartialOrd + Clone + Copy,
{
let time = Instant::now();
let mut steps = vec![arr.clone()];
if arr.len() <= 1 {
return (arr, steps, time.elapsed());
}
let rhs = &arr[..arr.len()/2];
let lhs = &arr[arr.len()/2..];
let sorted = merge_rec_stepped(rhs.to_vec(), lhs.to_vec(), &mut steps);
(sorted, steps, time.elapsed())
}
fn merge_rec<T>(mut rhs: Vec<T>, mut lhs: Vec<T>) -> Vec<T>
where T: PartialEq + PartialOrd + Clone + Copy,
{
let mut sorted = vec![];
if rhs.len() > 1 {
let new_rhs = &rhs[..rhs.len()/2];
let new_lhs = &rhs[rhs.len()/2..];
rhs = merge_rec(new_rhs.to_vec(), new_lhs.to_vec());
}
if lhs.len() > 1 {
let new_rhs = &lhs[..lhs.len()/2];
let new_lhs = &lhs[lhs.len()/2..];
lhs = merge_rec(new_rhs.to_vec(), new_lhs.to_vec());
}
let mut i = 0;
let mut j = 0;
while i < rhs.len() && j < lhs.len() {
if rhs[i] <= lhs[j] {
sorted.push(rhs[i]);
i += 1;
} else {
sorted.push(lhs[j]);
j += 1;
}
}
if i == rhs.len() {
for k in j..lhs.len() {
sorted.push(lhs[k]);
}
} else if j == lhs.len() {
for k in i..rhs.len() {
sorted.push(rhs[k]);
}
}
return sorted;
}
fn merge_rec_stepped<T>(mut rhs: Vec<T>, mut lhs: Vec<T>, steps: &mut Vec<Vec<T>>) -> Vec<T>
where T: PartialEq + PartialOrd + Clone + Copy,
{
let mut sorted = vec![];
if rhs.len() > 1 {
let new_rhs = &rhs[..rhs.len()/2];
let new_lhs = &rhs[rhs.len()/2..];
rhs = merge_rec_stepped(new_rhs.to_vec(), new_lhs.to_vec(), steps);
}
if lhs.len() > 1 {
let new_rhs = &lhs[..lhs.len()/2];
let new_lhs = &lhs[lhs.len()/2..];
lhs = merge_rec_stepped(new_rhs.to_vec(), new_lhs.to_vec(), steps);
}
let mut i = 0;
let mut j = 0;
while i < rhs.len() && j < lhs.len() {
if rhs[i] <= lhs[j] {
sorted.push(rhs[i]);
i += 1;
} else {
sorted.push(lhs[j]);
j += 1;
}
}
if i == rhs.len() {
for k in j..lhs.len() {
sorted.push(lhs[k]);
}
} else if j == lhs.len() {
for k in i..rhs.len() {
sorted.push(rhs[k]);
}
}
steps.push(sorted.clone());
return sorted;
}