refactor zad2 and 3 from lab2

This commit is contained in:
jacekpoz 2024-05-06 21:13:20 +02:00
parent 9c22f0dbb0
commit cc822b9f04
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8
10 changed files with 471 additions and 177 deletions

View file

@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
libsort = { path = "../zad1/libsort" }
libgen = { path = "../zad1/libgen" }
libsort = { path = "../../libsort" }
libgen = { path = "../../libgen" }

View file

@ -2,22 +2,22 @@ use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, sync::{Arc,
use std::io::{self, Write};
use libgen::gen_rand;
use libsort::{hybrid_sort, insertion_sort, quick_sort, SortResult};
use libsort::{hybrid_sort::HybridSort, insertion_sort::InsertionSort, quick_sort::QuickSort, Sort};
fn comp_avg(results_map: &HashMap<u64, Vec<SortResult>>) -> HashMap<u64, f64> {
fn comp_avg(results_map: &HashMap<u64, Vec<(u64, u64)>>) -> HashMap<u64, f64> {
results_map.iter()
.map(|(i, results)|
(*i, (results.iter()
.map(|res| res.comparisons)
.map(|res| res.0)
.sum::<u64>() as f64 / results.len() as f64)))
.collect()
}
fn swap_avg(results_map: &HashMap<u64, Vec<SortResult>>) -> HashMap<u64, f64> {
fn swap_avg(results_map: &HashMap<u64, Vec<(u64, u64)>>) -> HashMap<u64, f64> {
results_map.iter()
.map(|(i, results)|
(*i, (results.iter()
.map(|res| res.swaps)
.map(|res| res.1)
.sum::<u64>() as f64 / results.len() as f64)))
.collect()
}
@ -28,12 +28,12 @@ fn main() -> io::Result<()> {
.parse::<u64>()
.expect("k must be u64");
let insertion_results_small: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = Arc::new(RwLock::new(HashMap::new()));
let quick_results_small: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = Arc::new(RwLock::new(HashMap::new()));
let hybrid_results_small: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = Arc::new(RwLock::new(HashMap::new()));
let insertion_results_small: Arc<RwLock<HashMap<u64, Vec<(u64, u64)>>>> = Arc::new(RwLock::new(HashMap::new()));
let quick_results_small: Arc<RwLock<HashMap<u64, Vec<(u64, u64)>>>> = Arc::new(RwLock::new(HashMap::new()));
let hybrid_results_small: Arc<RwLock<HashMap<u64, Vec<(u64, u64)>>>> = Arc::new(RwLock::new(HashMap::new()));
let quick_results_large: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = Arc::new(RwLock::new(HashMap::new()));
let hybrid_results_large: Arc<RwLock<HashMap<u64, Vec<SortResult>>>> = Arc::new(RwLock::new(HashMap::new()));
let quick_results_large: Arc<RwLock<HashMap<u64, Vec<(u64, u64)>>>> = Arc::new(RwLock::new(HashMap::new()));
let hybrid_results_large: Arc<RwLock<HashMap<u64, Vec<(u64, u64)>>>> = Arc::new(RwLock::new(HashMap::new()));
let mut thread_handles = vec![];
@ -64,10 +64,18 @@ fn main() -> io::Result<()> {
irs.insert(n as u64, vec![]);
qrs.insert(n as u64, vec![]);
hrs.insert(n as u64, vec![]);
let mut insertion = InsertionSort::new(false);
let mut quick = QuickSort::new(false);
let mut hybrid = HybridSort::new(8, false);
for _ in 0..k {
irs.get_mut(&(n as u64)).unwrap().push(insertion_sort(&mut gen_rand(n as u64), false));
qrs.get_mut(&(n as u64)).unwrap().push(quick_sort(&mut gen_rand(n as u64), false));
hrs.get_mut(&(n as u64)).unwrap().push(hybrid_sort(&mut gen_rand(n as u64), 8, false));
insertion.sort_mut(&mut gen_rand(n as u64));
quick.sort_mut(&mut gen_rand(n as u64));
hybrid.sort_mut(&mut gen_rand(n as u64));
irs.get_mut(&(n as u64)).unwrap().push((insertion.num_comp(), insertion.num_swap()));
qrs.get_mut(&(n as u64)).unwrap().push((quick.num_comp(), quick.num_swap()));
hrs.get_mut(&(n as u64)).unwrap().push((hybrid.num_comp(), hybrid.num_swap()));
}
}
});
@ -90,9 +98,15 @@ fn main() -> io::Result<()> {
qrl.insert(n as u64, vec![]);
hrl.insert(n as u64, vec![]);
let mut quick = QuickSort::new(false);
let mut hybrid = HybridSort::new(8, false);
for _ in 0..k {
qrl.get_mut(&(n as u64)).unwrap().push(quick_sort(&mut gen_rand(n as u64), false));
hrl.get_mut(&(n as u64)).unwrap().push(hybrid_sort(&mut gen_rand(n as u64), 8, false));
quick.sort_mut(&mut gen_rand(n as u64));
hybrid.sort_mut(&mut gen_rand(n as u64));
qrl.get_mut(&(n as u64)).unwrap().push((quick.num_comp(), quick.num_swap()));
hrl.get_mut(&(n as u64)).unwrap().push((hybrid.num_comp(), hybrid.num_swap()));
}
}
});

View file

@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
libgen = { path = "../zad1/libgen" }
libsort = { path = "../zad1/libsort" }
libgen = { path = "../../libgen" }
libsort = { path = "../../libsort" }

View file

@ -5,25 +5,25 @@ mod mysort;
use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, io::{self, Write}};
use libgen::gen_rand;
use libsort::{is_sorted, print_list, SortResult};
use libsort::{is_sorted, merge_sort::MergeSort, my_sort::MySort, Sort};
use mergesort::mergesort;
use crate::mysort::mysort;
fn comp_avg(results_map: &HashMap<u64, Vec<SortResult>>) -> HashMap<u64, f64> {
fn comp_avg(results_map: &HashMap<u64, Vec<(u64, u64)>>) -> HashMap<u64, f64> {
results_map.iter()
.map(|(i, results)|
(*i, (results.iter()
.map(|res| res.comparisons)
.map(|res| res.0)
.sum::<u64>() as f64 / results.len() as f64)))
.collect()
}
fn swap_avg(results_map: &HashMap<u64, Vec<SortResult>>) -> HashMap<u64, f64> {
fn swap_avg(results_map: &HashMap<u64, Vec<(u64, u64)>>) -> HashMap<u64, f64> {
results_map.iter()
.map(|(i, results)|
(*i, (results.iter()
.map(|res| res.swaps)
.map(|res| res.1)
.sum::<u64>() as f64 / results.len() as f64)))
.collect()
}
@ -55,23 +55,25 @@ fn sort_stdin() -> io::Result<()> {
if print {
print!("input: ");
print_list(&input_list);
println!("{:?}", input_list);
println!();
}
let res = mysort(&mut list);
let mut my = MySort::new(print);
my.sort_mut(&mut list);
if print {
println!();
print!("input: ");
print_list(&input_list);
println!("{:?}", input_list);
println!();
print!("output: ");
print_list(&list);
println!("{:?}", list);
}
println!("swaps: {}", res.swaps);
println!("comparisons: {}", res.comparisons);
println!("swaps: {}", my.num_swap());
println!("comparisons: {}", my.num_comp());
println!("is sorted: {}", is_sorted(&list));
@ -88,31 +90,37 @@ fn main() -> io::Result<()> {
.parse::<u64>()
.expect("k must be u64");
let mut merge_results_small: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut my_results_small: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut merge_results_small: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
let mut my_results_small: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
for n in (10..=50).step_by(10) {
merge_results_small.insert(n, vec![]);
my_results_small.insert(n, vec![]);
let mut merge = MergeSort::new(false);
let mut my = MySort::new(false);
for _ in 0..k {
let mut res = SortResult::default();
mergesort(&mut gen_rand(n), &mut res);
merge_results_small.get_mut(&n).unwrap().push(res);
my_results_small.get_mut(&n).unwrap().push(mysort(&mut gen_rand(n)));
merge.sort_mut(&mut gen_rand(n));
my.sort_mut(&mut gen_rand(n));
merge_results_small.get_mut(&n).unwrap().push((merge.num_comp(), merge.num_swap()));
my_results_small.get_mut(&n).unwrap().push((my.num_comp(), my.num_swap()));
}
}
let mut merge_results_large: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut my_results_large: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut merge_results_large: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
let mut my_results_large: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
for n in (1000..=50000).step_by(1000) {
merge_results_large.insert(n, vec![]);
my_results_large.insert(n, vec![]);
let mut merge = MergeSort::new(false);
let mut my = MySort::new(false);
for _ in 0..k {
let mut res = SortResult::default();
mergesort(&mut gen_rand(n), &mut res);
merge_results_large.get_mut(&n).unwrap().push(res);
my_results_large.get_mut(&n).unwrap().push(mysort(&mut gen_rand(n)));
merge.sort_mut(&mut gen_rand(n));
my.sort_mut(&mut gen_rand(n));
merge_results_large.get_mut(&n).unwrap().push((merge.num_comp(), merge.num_swap()));
my_results_large.get_mut(&n).unwrap().push((my.num_comp(), my.num_swap()));
}
}

View file

@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
libgen = { path = "../zad1/libgen" }
libsort = { path = "../zad1/libsort" }
libgen = { path = "../../libgen" }
libsort = { path = "../../libsort" }

View file

@ -1,136 +1,22 @@
use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, io::{self, Write}};
use libgen::gen_rand;
use libsort::{is_sorted, print_list, quick_sort, SortResult};
use libsort::{dual_pivot_quick_sort::DualPivotQuickSort, is_sorted, quick_sort::{self, QuickSort}, Sort};
#[derive(PartialEq)]
enum CompareResult {
LESS, EQUAL, GREATER
}
fn compare(a: u64, b: u64, comparisons: &mut u64) -> CompareResult {
*comparisons += 1;
if a < b {
CompareResult::LESS
} else if a > b {
CompareResult::GREATER
} else {
CompareResult::EQUAL
}
}
fn swap(list: &mut [u64], i: usize, j: usize, swaps: &mut u64) {
*swaps += 1;
list.swap(i, j);
}
use CompareResult::*;
fn dual_pivot_partition(list: &mut [u64], res: &mut SortResult) -> (usize, usize) {
let mut comps = 0;
let mut swaps = 0;
if compare(list[0], list[list.len() - 1], &mut comps) == GREATER {
swap(list, 0, list.len() - 1, &mut swaps);
}
let mut l = 1;
let mut g = list.len() - 2;
let mut k = l;
let p = list[0];
let q = list[list.len() - 1];
while k <= g {
// l > s
if ((list.len() - 1) - g) > (l - 1) {
// list[k] >= q
if compare(list[k], q, &mut comps) != LESS {
while compare(list[g], q, &mut comps) == GREATER && k < g {
g -= 1;
}
swap(list, k, g, &mut swaps);
g -= 1;
if compare(list[k], p, &mut comps) == LESS {
swap(list, k, l, &mut swaps);
l += 1;
}
// list[k] < p
} else if compare(list[k], p, &mut comps) == LESS {
swap(list, k, l, &mut swaps);
l += 1;
}
// l < s
} else {
// list[k] < p
if compare(list[k], p, &mut comps) == LESS {
swap(list, k, l, &mut swaps);
l += 1;
// list[k] >= q
} else if compare(list[k], q, &mut comps) != LESS {
while compare(list[g], q, &mut comps) == GREATER && k < g {
g -= 1;
}
swap(list, k, g, &mut swaps);
g -= 1;
if compare(list[k], p, &mut comps) == LESS {
swap(list, k, l, &mut swaps);
l += 1;
}
}
}
k += 1;
}
l -= 1;
g += 1;
swap(list, 0, l, &mut swaps);
swap(list, list.len() - 1, g, &mut swaps);
res.comparisons += comps;
res.swaps += swaps;
(l, g)
}
fn dual_pivot_quick_sort(list: &mut [u64], print: bool) -> SortResult {
let mut res = SortResult::default();
if list.len() <= 1 {
return res;
}
let (lp, rp) = dual_pivot_partition(list, &mut res);
if print {
println!("left pivot = {lp}; right pivot = {rp}:");
print_list(&list);
}
let res1 = if lp == 0 { res.clone() } else { dual_pivot_quick_sort(&mut list[0..=(lp - 1)], print) };
let res2 = dual_pivot_quick_sort(&mut list[(lp + 1)..=(rp - 1)], print);
let res3 = dual_pivot_quick_sort(&mut list[(rp + 1)..], print);
res.comparisons += res1.comparisons + res2.comparisons + res3.comparisons;
res.swaps += res1.swaps + res2.swaps + res3.swaps;
res
}
fn comp_avg(results_map: &HashMap<u64, Vec<SortResult>>) -> HashMap<u64, f64> {
fn comp_avg(results_map: &HashMap<u64, Vec<(u64, u64)>>) -> HashMap<u64, f64> {
results_map.iter()
.map(|(i, results)|
(*i, (results.iter()
.map(|res| res.comparisons)
.map(|res| res.0)
.sum::<u64>() as f64 / results.len() as f64)))
.collect()
}
fn swap_avg(results_map: &HashMap<u64, Vec<SortResult>>) -> HashMap<u64, f64> {
fn swap_avg(results_map: &HashMap<u64, Vec<(u64, u64)>>) -> HashMap<u64, f64> {
results_map.iter()
.map(|(i, results)|
(*i, (results.iter()
.map(|res| res.swaps)
.map(|res| res.1)
.sum::<u64>() as f64 / results.len() as f64)))
.collect()
}
@ -162,23 +48,25 @@ fn sort_stdin() -> io::Result<()> {
if print {
print!("input: ");
print_list(&input_list);
println!("{:?}", input_list);
println!();
}
let res = dual_pivot_quick_sort(&mut list, print);
let mut dual_pivot_quick = DualPivotQuickSort::new(print);
dual_pivot_quick.sort_mut(&mut list);
if print {
println!();
print!("input: ");
print_list(&input_list);
println!("{:?}", input_list);
println!();
print!("output: ");
print_list(&list);
println!("{:?}", list);
}
println!("swaps: {}", res.swaps);
println!("comparisons: {}", res.comparisons);
println!("swaps: {}", dual_pivot_quick.num_swap());
println!("comparisons: {}", dual_pivot_quick.num_comp());
println!("is sorted: {}", is_sorted(&list));
@ -195,27 +83,37 @@ fn main() -> io::Result<()> {
.parse::<u64>()
.expect("k must be u64");
let mut quick_results_small: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut dual_pivot_results_small: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut quick_results_small: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
let mut dual_pivot_results_small: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
for n in (10..=50).step_by(10) {
quick_results_small.insert(n, vec![]);
dual_pivot_results_small.insert(n, vec![]);
let mut quick = QuickSort::new(false);
let mut dual_pivot_quick = DualPivotQuickSort::new(false);
for _ in 0..k {
quick_results_small.get_mut(&n).unwrap().push(quick_sort(&mut gen_rand(n), false));
dual_pivot_results_small.get_mut(&n).unwrap().push(dual_pivot_quick_sort(&mut gen_rand(n), false));
quick.sort_mut(&mut gen_rand(n));
dual_pivot_quick.sort_mut(&mut gen_rand(n));
quick_results_small.get_mut(&n).unwrap().push((quick.num_comp(), quick.num_swap()));
dual_pivot_results_small.get_mut(&n).unwrap().push((dual_pivot_quick.num_comp(), dual_pivot_quick.num_swap()));
}
}
let mut quick_results_large: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut dual_pivot_results_large: HashMap<u64, Vec<SortResult>> = HashMap::new();
let mut quick_results_large: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
let mut dual_pivot_results_large: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
for n in (1000..=50000).step_by(1000) {
quick_results_large.insert(n, vec![]);
dual_pivot_results_large.insert(n, vec![]);
let mut quick = QuickSort::new(false);
let mut dual_pivot_quick = DualPivotQuickSort::new(false);
for _ in 0..k {
quick_results_large.get_mut(&n).unwrap().push(quick_sort(&mut gen_rand(n), false));
dual_pivot_results_large.get_mut(&n).unwrap().push(dual_pivot_quick_sort(&mut gen_rand(n), false));
quick.sort_mut(&mut gen_rand(n));
dual_pivot_quick.sort_mut(&mut gen_rand(n));
quick_results_large.get_mut(&n).unwrap().push((quick.num_comp(), quick.num_swap()));
dual_pivot_results_large.get_mut(&n).unwrap().push((dual_pivot_quick.num_comp(), dual_pivot_quick.num_swap()));
}
}

View file

@ -0,0 +1,139 @@
use crate::{CompareResult, Sort};
pub struct DualPivotQuickSort {
comparisons: u64,
swaps: u64,
should_print: bool,
}
impl DualPivotQuickSort {
fn swap(&mut self, list: &mut Vec<u64>, i: usize, j: usize) {
self.swaps += 1;
list.swap(i, j);
}
fn compare(&mut self, a: u64, b: u64) -> CompareResult {
self.comparisons += 1;
if a < b {
CompareResult::LESS
} else if a > b {
CompareResult::GREATER
} else {
CompareResult::EQUAL
}
}
fn dual_pivot_partition(&mut self, list: &mut Vec<u64>) -> (usize, usize) {
use CompareResult::*;
if self.compare(list[0], list[list.len() - 1]) == GREATER {
self.swap(list, 0, list.len() - 1);
}
let mut l = 1;
let mut g = list.len() - 2;
let mut k = l;
let p = list[0];
let q = list[list.len() - 1];
while k <= g {
// l > s
if ((list.len() - 1) - g) > (l - 1) {
// list[k] >= q
if self.compare(list[k], q) != LESS {
while self.compare(list[g], q) == GREATER && k < g {
g -= 1;
}
self.swap(list, k, g);
g -= 1;
if self.compare(list[k], p) == LESS {
self.swap(list, k, l);
l += 1;
}
// list[k] < p
} else if self.compare(list[k], p) == LESS {
self.swap(list, k, l);
l += 1;
}
// l < s
} else {
// list[k] < p
if self.compare(list[k], p) == LESS {
self.swap(list, k, l);
l += 1;
// list[k] >= q
} else if self.compare(list[k], q) != LESS {
while self.compare(list[g], q) == GREATER && k < g {
g -= 1;
}
self.swap(list, k, g);
g -= 1;
if self.compare(list[k], p) == LESS {
self.swap(list, k, l);
l += 1;
}
}
}
k += 1;
}
l -= 1;
g += 1;
self.swap(list, 0, l);
self.swap(list, list.len() - 1, g);
(l, g)
}
}
impl Sort for DualPivotQuickSort {
fn new(should_print: bool) -> Self {
Self {
comparisons: 0,
swaps: 0,
should_print,
}
}
fn sort_mut(&mut self, list: &mut Vec<u64>) {
if list.len() <= 1 {
return;
}
let (lp, rp) = self.dual_pivot_partition(list);
if self.should_print {
println!("left pivot = {lp}; right pivot = {rp}:");
println!("{:?}", list);
}
let mut vec = list.clone();
vec.drain(lp..);
self.sort_mut(&mut vec);
let mut vec = list.clone();
vec.drain(rp..);
vec.drain(..=lp);
self.sort_mut(&mut vec);
let mut vec = list.clone();
vec.drain(..=rp);
self.sort_mut(&mut vec);
}
fn num_comp(&self) -> u64 {
self.comparisons
}
fn num_swap(&self) -> u64 {
self.swaps
}
fn reset_state(&mut self) {
self.comparisons = 0;
self.swaps = 0;
}
}

View file

@ -1,5 +1,8 @@
pub mod insertion_sort;
pub mod dual_pivot_quick_sort;
pub mod hybrid_sort;
pub mod merge_sort;
pub mod my_sort;
pub mod quick_sort;
pub trait Sort {

95
libsort/src/merge_sort.rs Normal file
View file

@ -0,0 +1,95 @@
use crate::{CompareResult, Sort};
pub struct MergeSort {
comparisons: u64,
swaps: u64,
}
impl MergeSort {
fn compare(&mut self, a: u64, b: u64) -> CompareResult {
self.comparisons += 1;
if a < b {
CompareResult::LESS
} else if a > b {
CompareResult::GREATER
} else {
CompareResult::EQUAL
}
}
pub fn merge(&mut self, list1: &Vec<u64>, list2: &Vec<u64>) -> Vec<u64> {
let mut ret = vec![];
let mut i = 0;
let mut j = 0;
while i < list1.len() && j < list2.len() {
use CompareResult::*;
if self.compare(list1[i], list2[j]) == LESS {
ret.push(list1[i]);
i = i + 1;
} else {
ret.push(list2[j]);
j = j + 1;
}
}
if i < list1.len() {
while i < list1.len() {
ret.push(list1[i]);
i = i + 1;
}
}
if j < list2.len() {
while j < list2.len() {
ret.push(list2[j]);
j = j + 1;
}
}
ret
}
}
impl Sort for MergeSort {
fn new(_should_print: bool) -> Self {
Self {
comparisons: 0,
swaps: 0,
}
}
fn sort_mut(&mut self, list: &mut Vec<u64>) {
if list.len() > 1 {
let size = list.len() / 2;
let mut vec = list.clone();
vec.drain(size..);
self.sort_mut(&mut vec);
let left = vec;
let mut vec = list.clone();
vec.drain(..size);
self.sort_mut(&mut vec);
let right = vec;
let merged = self.merge(&left, &right);
*list = merged;
}
}
fn num_comp(&self) -> u64 {
self.comparisons
}
fn num_swap(&self) -> u64 {
self.swaps
}
fn reset_state(&mut self) {
self.comparisons = 0;
self.swaps = 0;
}
}

137
libsort/src/my_sort.rs Normal file
View file

@ -0,0 +1,137 @@
use crate::{merge_sort::MergeSort, CompareResult, Sort};
pub struct MySort {
comparisons: u64,
swaps: u64,
merge: MergeSort,
}
impl MySort {
fn compare(&mut self, a: u64, b: u64) -> CompareResult {
self.comparisons += 1;
if a < b {
CompareResult::LESS
} else if a > b {
CompareResult::GREATER
} else {
CompareResult::EQUAL
}
}
fn extend_run_left(&mut self, list: &Vec<u64>, mut i: usize) -> usize {
use CompareResult::*;
while i > 0 && self.compare(list[i - 1], list[i]) != GREATER {
i -= 1;
}
i
}
fn extend_run_right(&mut self, list: &Vec<u64>, mut i: usize) -> usize {
use CompareResult::*;
while i < list.len() - 1 && self.compare(list[i], list[i + 1]) != GREATER {
i += 1;
}
i
}
fn _mysort(&mut self, list: &mut Vec<u64>, low: usize, high: usize, e: usize, s: usize) {
if e == high || s == low {
return;
}
let mid = low + (high - low) / 2;
if mid <= e {
self._mysort(list, e + 1, high, e + 1, s);
let mut left = list.clone();
left.drain(e + 1..);
left.drain(..low);
let mut right = list.clone();
right.drain(high + 1..);
right.drain(..=e);
list.copy_from_slice(&self.merge.merge(&left, &right));
self.comparisons += self.merge.num_comp();
self.swaps += self.merge.num_swap();
} else if mid >= s {
self._mysort(list, low, s - 1, e, s - 1);
let mut left = list.clone();
left.drain(s..);
left.drain(..low);
let mut right = list.clone();
right.drain(high + 1..);
right.drain(..s);
list.copy_from_slice(&self.merge.merge(&left, &right));
self.comparisons += self.merge.num_comp();
self.swaps += self.merge.num_swap();
} else {
let i = self.extend_run_left(list, low);
let j = self.extend_run_right(list, high);
if i == low && j == high {
return;
}
if mid - i < j - mid {
self._mysort(list, low, i - 1, e, i - 1);
self._mysort(list, i, high, j, s);
let mut left = list.clone();
left.drain(i..);
left.drain(..low);
let mut right = list.clone();
right.drain(high + 1..);
right.drain(..i);
list.copy_from_slice(&self.merge.merge(&left, &right));
self.comparisons += self.merge.num_comp();
self.swaps += self.merge.num_swap();
} else {
self._mysort(list, low, j, e, i);
self._mysort(list, j + 1, high, j + 1, s);
let mut left = list.clone();
left.drain(j + 1..);
left.drain(..low);
let mut right = list.clone();
right.drain(high + 1..);
right.drain(..=j);
list.copy_from_slice(&self.merge.merge(&left, &right));
self.comparisons += self.merge.num_comp();
self.swaps += self.merge.num_swap();
}
}
}
}
impl Sort for MySort {
fn new(should_print: bool) -> Self {
Self {
comparisons: 0,
swaps: 0,
merge: MergeSort::new(should_print),
}
}
fn sort_mut(&mut self, list: &mut Vec<u64>) {
self._mysort(list, 0, list.len() - 1, 0, list.len() - 1)
}
fn num_comp(&self) -> u64 {
self.comparisons
}
fn num_swap(&self) -> u64 {
self.swaps
}
fn reset_state(&mut self) {
self.comparisons = 0;
self.swaps = 0;
}
}