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"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libsort = { path = "../zad1/libsort" }
|
libsort = { path = "../../libsort" }
|
||||||
libgen = { path = "../zad1/libgen" }
|
libgen = { path = "../../libgen" }
|
||||||
|
|
|
@ -2,22 +2,22 @@ use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, sync::{Arc,
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use libgen::gen_rand;
|
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()
|
results_map.iter()
|
||||||
.map(|(i, results)|
|
.map(|(i, results)|
|
||||||
(*i, (results.iter()
|
(*i, (results.iter()
|
||||||
.map(|res| res.comparisons)
|
.map(|res| res.0)
|
||||||
.sum::<u64>() as f64 / results.len() as f64)))
|
.sum::<u64>() as f64 / results.len() as f64)))
|
||||||
.collect()
|
.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()
|
results_map.iter()
|
||||||
.map(|(i, results)|
|
.map(|(i, results)|
|
||||||
(*i, (results.iter()
|
(*i, (results.iter()
|
||||||
.map(|res| res.swaps)
|
.map(|res| res.1)
|
||||||
.sum::<u64>() as f64 / results.len() as f64)))
|
.sum::<u64>() as f64 / results.len() as f64)))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,12 @@ fn main() -> io::Result<()> {
|
||||||
.parse::<u64>()
|
.parse::<u64>()
|
||||||
.expect("k must be u64");
|
.expect("k must be u64");
|
||||||
|
|
||||||
let insertion_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<SortResult>>>> = 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<SortResult>>>> = 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 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<SortResult>>>> = 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![];
|
let mut thread_handles = vec![];
|
||||||
|
|
||||||
|
@ -64,10 +64,18 @@ fn main() -> io::Result<()> {
|
||||||
irs.insert(n as u64, vec![]);
|
irs.insert(n as u64, vec![]);
|
||||||
qrs.insert(n as u64, vec![]);
|
qrs.insert(n as u64, vec![]);
|
||||||
hrs.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 {
|
for _ in 0..k {
|
||||||
irs.get_mut(&(n as u64)).unwrap().push(insertion_sort(&mut gen_rand(n as u64), false));
|
insertion.sort_mut(&mut gen_rand(n as u64));
|
||||||
qrs.get_mut(&(n as u64)).unwrap().push(quick_sort(&mut gen_rand(n as u64), false));
|
quick.sort_mut(&mut gen_rand(n as u64));
|
||||||
hrs.get_mut(&(n as u64)).unwrap().push(hybrid_sort(&mut gen_rand(n as u64), 8, false));
|
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![]);
|
qrl.insert(n as u64, vec![]);
|
||||||
hrl.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 {
|
for _ in 0..k {
|
||||||
qrl.get_mut(&(n as u64)).unwrap().push(quick_sort(&mut gen_rand(n as u64), false));
|
quick.sort_mut(&mut gen_rand(n as u64));
|
||||||
hrl.get_mut(&(n as u64)).unwrap().push(hybrid_sort(&mut gen_rand(n as u64), 8, false));
|
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"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libgen = { path = "../zad1/libgen" }
|
libgen = { path = "../../libgen" }
|
||||||
libsort = { path = "../zad1/libsort" }
|
libsort = { path = "../../libsort" }
|
||||||
|
|
|
@ -5,25 +5,25 @@ mod mysort;
|
||||||
use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, io::{self, Write}};
|
use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, io::{self, Write}};
|
||||||
|
|
||||||
use libgen::gen_rand;
|
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 mergesort::mergesort;
|
||||||
|
|
||||||
use crate::mysort::mysort;
|
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()
|
results_map.iter()
|
||||||
.map(|(i, results)|
|
.map(|(i, results)|
|
||||||
(*i, (results.iter()
|
(*i, (results.iter()
|
||||||
.map(|res| res.comparisons)
|
.map(|res| res.0)
|
||||||
.sum::<u64>() as f64 / results.len() as f64)))
|
.sum::<u64>() as f64 / results.len() as f64)))
|
||||||
.collect()
|
.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()
|
results_map.iter()
|
||||||
.map(|(i, results)|
|
.map(|(i, results)|
|
||||||
(*i, (results.iter()
|
(*i, (results.iter()
|
||||||
.map(|res| res.swaps)
|
.map(|res| res.1)
|
||||||
.sum::<u64>() as f64 / results.len() as f64)))
|
.sum::<u64>() as f64 / results.len() as f64)))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -55,23 +55,25 @@ fn sort_stdin() -> io::Result<()> {
|
||||||
|
|
||||||
if print {
|
if print {
|
||||||
print!("input: ");
|
print!("input: ");
|
||||||
print_list(&input_list);
|
println!("{:?}", input_list);
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = mysort(&mut list);
|
let mut my = MySort::new(print);
|
||||||
|
|
||||||
|
my.sort_mut(&mut list);
|
||||||
|
|
||||||
if print {
|
if print {
|
||||||
println!();
|
println!();
|
||||||
print!("input: ");
|
print!("input: ");
|
||||||
print_list(&input_list);
|
println!("{:?}", input_list);
|
||||||
println!();
|
println!();
|
||||||
print!("output: ");
|
print!("output: ");
|
||||||
print_list(&list);
|
println!("{:?}", list);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("swaps: {}", res.swaps);
|
println!("swaps: {}", my.num_swap());
|
||||||
println!("comparisons: {}", res.comparisons);
|
println!("comparisons: {}", my.num_comp());
|
||||||
|
|
||||||
println!("is sorted: {}", is_sorted(&list));
|
println!("is sorted: {}", is_sorted(&list));
|
||||||
|
|
||||||
|
@ -88,31 +90,37 @@ fn main() -> io::Result<()> {
|
||||||
.parse::<u64>()
|
.parse::<u64>()
|
||||||
.expect("k must be u64");
|
.expect("k must be u64");
|
||||||
|
|
||||||
let mut merge_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<SortResult>> = HashMap::new();
|
let mut my_results_small: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
|
||||||
|
|
||||||
for n in (10..=50).step_by(10) {
|
for n in (10..=50).step_by(10) {
|
||||||
merge_results_small.insert(n, vec![]);
|
merge_results_small.insert(n, vec![]);
|
||||||
my_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 {
|
for _ in 0..k {
|
||||||
let mut res = SortResult::default();
|
merge.sort_mut(&mut gen_rand(n));
|
||||||
mergesort(&mut gen_rand(n), &mut res);
|
my.sort_mut(&mut gen_rand(n));
|
||||||
merge_results_small.get_mut(&n).unwrap().push(res);
|
merge_results_small.get_mut(&n).unwrap().push((merge.num_comp(), merge.num_swap()));
|
||||||
my_results_small.get_mut(&n).unwrap().push(mysort(&mut gen_rand(n)));
|
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 merge_results_large: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
|
||||||
let mut my_results_large: HashMap<u64, Vec<SortResult>> = HashMap::new();
|
let mut my_results_large: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
|
||||||
|
|
||||||
for n in (1000..=50000).step_by(1000) {
|
for n in (1000..=50000).step_by(1000) {
|
||||||
merge_results_large.insert(n, vec![]);
|
merge_results_large.insert(n, vec![]);
|
||||||
my_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 {
|
for _ in 0..k {
|
||||||
let mut res = SortResult::default();
|
merge.sort_mut(&mut gen_rand(n));
|
||||||
mergesort(&mut gen_rand(n), &mut res);
|
my.sort_mut(&mut gen_rand(n));
|
||||||
merge_results_large.get_mut(&n).unwrap().push(res);
|
merge_results_large.get_mut(&n).unwrap().push((merge.num_comp(), merge.num_swap()));
|
||||||
my_results_large.get_mut(&n).unwrap().push(mysort(&mut gen_rand(n)));
|
my_results_large.get_mut(&n).unwrap().push((my.num_comp(), my.num_swap()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,5 +4,5 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libgen = { path = "../zad1/libgen" }
|
libgen = { path = "../../libgen" }
|
||||||
libsort = { path = "../zad1/libsort" }
|
libsort = { path = "../../libsort" }
|
||||||
|
|
|
@ -1,136 +1,22 @@
|
||||||
use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, io::{self, Write}};
|
use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, io::{self, Write}};
|
||||||
|
|
||||||
use libgen::gen_rand;
|
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)]
|
fn comp_avg(results_map: &HashMap<u64, Vec<(u64, u64)>>) -> HashMap<u64, f64> {
|
||||||
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> {
|
|
||||||
results_map.iter()
|
results_map.iter()
|
||||||
.map(|(i, results)|
|
.map(|(i, results)|
|
||||||
(*i, (results.iter()
|
(*i, (results.iter()
|
||||||
.map(|res| res.comparisons)
|
.map(|res| res.0)
|
||||||
.sum::<u64>() as f64 / results.len() as f64)))
|
.sum::<u64>() as f64 / results.len() as f64)))
|
||||||
.collect()
|
.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()
|
results_map.iter()
|
||||||
.map(|(i, results)|
|
.map(|(i, results)|
|
||||||
(*i, (results.iter()
|
(*i, (results.iter()
|
||||||
.map(|res| res.swaps)
|
.map(|res| res.1)
|
||||||
.sum::<u64>() as f64 / results.len() as f64)))
|
.sum::<u64>() as f64 / results.len() as f64)))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -162,23 +48,25 @@ fn sort_stdin() -> io::Result<()> {
|
||||||
|
|
||||||
if print {
|
if print {
|
||||||
print!("input: ");
|
print!("input: ");
|
||||||
print_list(&input_list);
|
println!("{:?}", input_list);
|
||||||
println!();
|
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 {
|
if print {
|
||||||
println!();
|
println!();
|
||||||
print!("input: ");
|
print!("input: ");
|
||||||
print_list(&input_list);
|
println!("{:?}", input_list);
|
||||||
println!();
|
println!();
|
||||||
print!("output: ");
|
print!("output: ");
|
||||||
print_list(&list);
|
println!("{:?}", list);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("swaps: {}", res.swaps);
|
println!("swaps: {}", dual_pivot_quick.num_swap());
|
||||||
println!("comparisons: {}", res.comparisons);
|
println!("comparisons: {}", dual_pivot_quick.num_comp());
|
||||||
|
|
||||||
println!("is sorted: {}", is_sorted(&list));
|
println!("is sorted: {}", is_sorted(&list));
|
||||||
|
|
||||||
|
@ -195,27 +83,37 @@ fn main() -> io::Result<()> {
|
||||||
.parse::<u64>()
|
.parse::<u64>()
|
||||||
.expect("k must be u64");
|
.expect("k must be u64");
|
||||||
|
|
||||||
let mut quick_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<SortResult>> = HashMap::new();
|
let mut dual_pivot_results_small: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
|
||||||
|
|
||||||
for n in (10..=50).step_by(10) {
|
for n in (10..=50).step_by(10) {
|
||||||
quick_results_small.insert(n, vec![]);
|
quick_results_small.insert(n, vec![]);
|
||||||
dual_pivot_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 {
|
for _ in 0..k {
|
||||||
quick_results_small.get_mut(&n).unwrap().push(quick_sort(&mut gen_rand(n), false));
|
quick.sort_mut(&mut gen_rand(n));
|
||||||
dual_pivot_results_small.get_mut(&n).unwrap().push(dual_pivot_quick_sort(&mut gen_rand(n), false));
|
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 quick_results_large: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
|
||||||
let mut dual_pivot_results_large: HashMap<u64, Vec<SortResult>> = HashMap::new();
|
let mut dual_pivot_results_large: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
|
||||||
|
|
||||||
for n in (1000..=50000).step_by(1000) {
|
for n in (1000..=50000).step_by(1000) {
|
||||||
quick_results_large.insert(n, vec![]);
|
quick_results_large.insert(n, vec![]);
|
||||||
dual_pivot_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 {
|
for _ in 0..k {
|
||||||
quick_results_large.get_mut(&n).unwrap().push(quick_sort(&mut gen_rand(n), false));
|
quick.sort_mut(&mut gen_rand(n));
|
||||||
dual_pivot_results_large.get_mut(&n).unwrap().push(dual_pivot_quick_sort(&mut gen_rand(n), false));
|
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 insertion_sort;
|
||||||
|
pub mod dual_pivot_quick_sort;
|
||||||
pub mod hybrid_sort;
|
pub mod hybrid_sort;
|
||||||
|
pub mod merge_sort;
|
||||||
|
pub mod my_sort;
|
||||||
pub mod quick_sort;
|
pub mod quick_sort;
|
||||||
|
|
||||||
pub trait 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