refactor zad2 and 3 from lab2
This commit is contained in:
parent
9c22f0dbb0
commit
cc822b9f04
10 changed files with 471 additions and 177 deletions
|
@ -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" }
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
139
libsort/src/dual_pivot_quick_sort.rs
Normal file
139
libsort/src/dual_pivot_quick_sort.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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
95
libsort/src/merge_sort.rs
Normal 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
137
libsort/src/my_sort.rs
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue