From 6e52722bdba5a7ce7d3162bb04fa27f226cdc847 Mon Sep 17 00:00:00 2001 From: jacekpoz Date: Mon, 6 May 2024 11:22:57 +0200 Subject: [PATCH] fix partition, also fixes select --- lab3/libsort/src/lib.rs | 119 +++++++++++++++------------------------ lab3/libsort/src/main.rs | 18 +++++- 2 files changed, 61 insertions(+), 76 deletions(-) diff --git a/lab3/libsort/src/lib.rs b/lab3/libsort/src/lib.rs index 774d9c8..962b3b4 100644 --- a/lab3/libsort/src/lib.rs +++ b/lab3/libsort/src/lib.rs @@ -1,85 +1,53 @@ use rand::{thread_rng, Rng}; -fn partition_diff(arr: &mut [u64], lo: usize, hi: usize, pivot: usize) -> usize { - let mut i = lo as i64 - 1; - for j in lo..hi { - if arr[j] == arr[pivot] { - i = j as i64; +pub fn insertion_sort_mut(list: &mut [u64]) { + for i in 1..list.len() { + let mut j = i as usize; + + while j > 0 && list[j - 1] > list[j] { + list.swap(j - 1, j); + j -= 1; + } + } +} + +pub fn insertion_sort(list: &[u64]) -> Vec { + let mut clone = Vec::from(list); + insertion_sort_mut(&mut clone); + clone +} + +fn partition(arr: &mut [u64], lo: usize, hi: usize, pivot: u64) -> usize { + let mut pivot_index = lo; + for i in lo..=hi { + if arr[i] == pivot { + pivot_index = i; break; } } - if i != lo as i64 - 1 { - arr.swap(hi - 1, i as usize); + if pivot_index != lo { + arr.swap(pivot_index, lo); + pivot_index = lo; } - - let mut k = lo; - - for j in lo..(hi - 1) { - if arr[j] < arr[pivot] { - arr.swap(j, k); - k += 1; + let mut j = lo; + for i in (lo + 1)..=hi { + if arr[pivot_index] > arr[i] { + j += 1; + arr.swap(j, i); } } - - arr.swap(hi - 1, k); - - k + arr.swap(j, lo); + j } -// pub fn lomuto_partition(arr: &mut [u64], lo: usize, hi: usize, pivot: usize) -> usize { -// println!("called lomuto_partition({:?}, {}, {}, {})", arr, lo, hi, pivot); -// let mut swap = 0; -// -// for i in lo..pivot { -// if arr[i] < arr[pivot] { -// if swap != i { -// arr.swap(swap, i); -// } -// swap += 1; -// } -// } -// -// if swap != pivot { -// arr.swap(swap, pivot); -// } -// -// swap -// } -// pub fn partition(arr: &mut [u64], lo: usize, hi: usize, pivot: usize) -> usize { -// println!("called partition({:?}, {}, {}, {})", arr, lo, hi, pivot); -// let mut i = lo; -// let mut j = hi - 1; -// -// loop { -// while arr[i] < arr[pivot] { -// println!("partition i: {i}"); -// i += 1; -// } -// while j > 0 && arr[j] > arr[pivot] { -// j -= 1; -// } -// if j == 0 || i >= j { -// break; -// } else if arr[i] == arr[j] { -// i += 1; -// j -= 1; -// } else { -// arr.swap(i, j); -// } -// } -// arr.swap(i, pivot); -// i -// } - pub fn rand_partition(arr: &mut [u64], lo: usize, hi: usize) -> usize { let pivot = thread_rng().gen_range(lo..hi); - partition_diff(arr, lo, hi, pivot) + partition(arr, lo, hi, arr[pivot]) } fn _rand_select(arr: &mut [u64], lo: usize, hi: usize, k: usize) -> (usize, u64) { - // println!("called _rand_select({:?}, {}, {}, {})", arr, lo, hi, k); - if lo + 1 == hi { + if lo == hi { return (lo, arr[lo]); } let r = rand_partition(arr, lo, hi); @@ -98,22 +66,25 @@ pub fn rand_select(arr: &mut [u64], k: usize) -> (usize, u64) { } fn _select(arr: &mut [u64], lo: usize, hi: usize, k: usize) -> (usize, u64) { - // println!("called _select({:?}, {}, {}, {})", arr, lo, hi, k); - if lo + 1 == hi { + if lo == hi { return (lo, arr[lo]); } - let mut medians = arr.chunks(5) - .map(|chunk| chunk[chunk.len() / 2]) + let mut medians: Vec = vec![]; + let mut chunks = arr.chunks(5) .collect::>(); + for chunk in chunks.iter_mut() { + let chunk = insertion_sort(chunk); + medians.push(chunk[chunk.len() / 2]); + } + let n = hi - lo; - let (pivot, _) = _select(&mut medians, 0, n.div_ceil(5), (n.div_ceil(5) - 1).div_ceil(2)); - // println!("calling partition from _select"); - let r = partition_diff(arr, lo, hi, pivot); - // println!("_select r: {r}"); + let (_, pivot) = _select(&mut medians, 0, n.div_ceil(5) - 1, (n.div_ceil(5) - 1).div_ceil(2)); + let r = partition(arr, lo, hi, pivot); let i = r - lo + 1; + if i == k { return (r, arr[r]); } else if i < k { diff --git a/lab3/libsort/src/main.rs b/lab3/libsort/src/main.rs index fe3563f..360e444 100644 --- a/lab3/libsort/src/main.rs +++ b/lab3/libsort/src/main.rs @@ -1,6 +1,20 @@ use libsort::{select, rand_select}; fn main() { - println!("select: {:?}", select(&mut [3, 1, 9, 20, 3, 5, 31, 8, 29, 34, 2], 5)); - println!("rand_select: {:?}", rand_select(&mut [3, 1, 9, 20, 3, 5, 31, 8, 29, 34, 2], 5)); + let arr = [3, 28, 9, 2, 4, 42, 23, 123, 24, 12, 43, 287, 723, 61]; + print!("select: "); + for pos in 1..=arr.len() { + // println!("input: {:?}", arr); + // println!("positional statistic: {}", pos); + // println!("select: {:?}", select(&mut arr.clone(), pos).1); + // println!("rand_select: {:?}", rand_select(&mut arr.clone(), pos).1); + print!("{} ", select(&mut arr.clone(), pos).1); + } + print!("\n"); + + print!("rand_select: "); + for pos in 1..=arr.len() { + print!("{} ", rand_select(&mut arr.clone(), pos).1); + } + print!("\n"); }